Beispiel #1
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for AFS marker
            if (!((fileReader.Read_32bitsBE(offset) == 0x48473200) &&
                  (fileReader.Read_32bitsBE(offset + 4) == 0x03000000) &&
                  (fileReader.Read_32bitsBE(offset + 8) == 0x02000000)))
            {
                return(null);
            }

            //string archiveName = fileReader.Read_String(offset + 0x08, 0x50);
            uint sizeOfEntireFile = fileReader.Read_32bits(offset + 0x0c);

            if ((sizeOfEntireFile == 0) || (sizeOfEntireFile > file.FileSize))
            {
                return(null);
            }

            uint fileCount        = (uint)fileReader.Read_32bits(offset + 0x20);
            uint offsetOfFilename = (uint)fileReader.Read_32bits(offset + 0x2C);
            uint offsetOfFileInfo = (uint)fileReader.Read_32bits(offset + 0x24);

            byte[] buffer           = fileReader.Read(offset + offsetOfFileInfo, (fileCount * 0x0c));
            byte[] bufferOffsetName = fileReader.Read(offset + offsetOfFilename, (fileCount * 0x04));

            uint OffsetSubstract = MemoryReader.ReadLong(ref bufferOffsetName, 0);

            if (OffsetSubstract > sizeOfEntireFile)
            {
                return(null);
            }

            byte[] bufferFileName = fileReader.Read(offset + offsetOfFilename + (fileCount * 0x04), sizeOfEntireFile - OffsetSubstract);

            for (uint i = 0; i < fileCount; i++)
            {
                uint   fileOffset       = MemoryReader.ReadLong(ref buffer, (i * 0x0c) + 0x08);
                uint   fileSize         = MemoryReader.ReadLong(ref buffer, (i * 0x0c) + 0x04);
                string filename         = string.Empty;
                uint   OffsetofFilename = MemoryReader.ReadLong(ref bufferOffsetName, (i * 0x04));

                filename = MemoryReader.GetString(ref bufferFileName, OffsetofFilename - OffsetSubstract, 0x255);

                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".PAK")
            {
                return(null);
            }

            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for marker ID
            if ((fileReader.Read_16bits(offset + 0x0A) != 0xA3DA))
            {
                return(null);
            }

            uint fileCount      = (uint)fileReader.Read_32bits(offset + 0x08) ^ 0xa3da79b6;
            uint filenameSize   = fileReader.Read_32bits(offset + 0x0C);
            uint folderNameSize = fileReader.Read_32bits(offset + 0x10);

            byte[] folderName = fileReader.Read(offset + 0x14, folderNameSize);
            for (int i = 0; i < folderNameSize; i++)
            {
                folderName[i] = (byte)(folderName[i] ^ 0xC5);
            }
            string folder = MemoryReader.GetString(ref folderName, 0);

            byte[] buffer     = fileReader.Read(offset + 0x14 + folderNameSize + 1, (fileCount * 0x10));
            byte[] bufferName = fileReader.Read(offset + 0x14 + folderNameSize + 1 + (fileCount * 0x10), filenameSize);
            for (int i = 0; i < filenameSize; i++)
            {
                bufferName[i] = (byte)(bufferName[i] ^ 0xB5);
            }

            for (uint i = 0; i < fileCount; i++)
            {
                uint   fileNameOffset = MemoryReader.ReadLong(ref buffer, (i * 0x10));
                uint   fileOffset     = MemoryReader.ReadLong(ref buffer, (i * 0x10) + 0x04);
                uint   fileSize       = MemoryReader.ReadLong(ref buffer, (i * 0x10) + 0x08);
                string filename       = string.Empty;
                filename = MemoryReader.GetString(ref bufferName, fileNameOffset);

                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            UInt64 offset = file.FileStartOffset;

            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".PSP")
            {
                return(null);
            }

            if ((fileReader.Read_32bitsBE(offset) != 0x01000010) && (fileReader.Read_32bitsBE(offset) != 0x434C5500))
            {
                return(null);
            }

            FST tmpFST = new FST();

            uint fileCount  = (uint)fileReader.Read_32bits(offset + 0x0C);
            uint bufferSize = (uint)fileReader.Read_32bits(offset + 0x08);

            byte[] buffer = fileReader.Read(offset + 0x20, bufferSize);

            for (uint i = 0; i < fileCount; i++)
            {
                uint fileOffset = MemoryReader.ReadLong(ref buffer, (i * 0x10) + 0x08);
                uint fileSize   = MemoryReader.ReadLong(ref buffer, (i * 0x10) + 0x04);
                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, string.Empty, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
Beispiel #4
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".XAD")
            {
                return(null);
            }

            byte[] filenameBuffer = null;

            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for AFS marker
            if ((fileReader.Read_32bitsBE(offset + 0x10) != 0x58444100) && (fileReader.Read_32bitsBE(offset + 0x14) != 0x82000000))
            {
                return(null);
            }

            //string archiveName = fileReader.Read_String(offset + 0x08, 0x50);
            uint fileCount = fileReader.Read_32bits(offset + 0x04);

            byte[] buffer         = fileReader.Read(offset + 0x08, (fileCount * 8));
            UInt64 filenameOffset = fileReader.Read_32bits(offset + 0x08 + (fileCount * 8));

            if (filenameOffset != 0)
            {
                uint filenameSize = fileReader.Read_32bits(offset + 0x08 + (fileCount * 8) + 4);
                filenameBuffer = fileReader.Read(offset + filenameOffset, filenameSize);
            }

            for (uint i = 0; i < fileCount; i++)
            {
                uint   fileOffset = MemoryReader.ReadLong(ref buffer, (i * 8));
                uint   fileSize   = MemoryReader.ReadLong(ref buffer, (i * 8) + 0x04);
                string filename   = string.Empty;

                if (filenameOffset != 0)
                {
                    filename = MemoryReader.GetString(ref filenameBuffer, (i * 0x30), 0x20);
                }

                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
Beispiel #5
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for ARC marker
            if ((fileReader.Read_32bitsBE(offset) != 0x41524300))
            {
                return(null);
            }

            //string archiveName = fileReader.Read_String(offset + 0x08, 0x50);
            uint fileCount     = (uint)fileReader.Read_32bits(offset + 0x0C);
            uint offset_adding = (uint)fileReader.Read_32bits(offset + 0x18);
            uint offset_name   = (uint)fileReader.Read_32bits(offset + 0x10);

            if ((offset_adding == 0) || (offset_adding > file.FileSize))
            {
                return(null);
            }

            if ((offset_name == 0) || (offset_name > offset_adding))
            {
                return(null);
            }

            byte[] buffer_name = fileReader.Read(offset + offset_name, offset_adding - offset_name);

            // long filenameOffset = fileReader.Read_32bits(offset + 0x08 + (fileCount * 8));

            // if (filenameOffset != 0)
            //{
            //    uint filenameSize = fileReader.Read_32bits(offset + 0x08 + (fileCount * 8) + 4);
            //    filenameBuffer = fileReader.Read(offset + filenameOffset, filenameSize);
            //}

            for (uint i = 0; i < fileCount; i++)
            {
                UInt64 fileOffset = MemoryReader.ReadLong(ref buffer_name, (i * 0x18));
                uint   fileSize   = MemoryReader.ReadLong(ref buffer_name, (i * 0x18) + 0x04);
                string filename   = string.Empty;

                if (fileOffset != 0)
                {
                    fileOffset += offset_adding;
                    uint filenameOffset = MemoryReader.ReadLong(ref buffer_name, (i * 0x18) + 0x10);
                    filename = MemoryReader.GetString(ref buffer_name, (fileCount * 0x18) + filenameOffset, 0xff);
                    tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
                }
            }

            return(tmpFST);
        }
Beispiel #6
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST    tmpFST       = new FST();
            UInt64 offset       = file.FileStartOffset;
            uint   offsetBuffer = 0;

            bool bigEndian = true;

            // check for BIGF marker
            if (fileReader.Read_32bitsBE(offset) != 0x42494746)
            {
                return(null);
            }

            if (fileReader.Read_32bitsBE(offset + 4) == file.FileSize)
            {
                bigEndian = false;
            }

            uint fileCount, filenameSize, fileOffset, fileSize;

            if (bigEndian)
            {
                fileCount    = (uint)fileReader.Read_32bits(offset + 0x08);
                filenameSize = fileReader.Read_32bits(offset + 0x0C) - 0x10;
            }
            else
            {
                fileCount    = (uint)fileReader.Read_32bitsBE(offset + 0x08);
                filenameSize = fileReader.Read_32bitsBE(offset + 0x0C) - 0x10;
            }

            byte[] buffer = fileReader.Read(offset + 0x10, filenameSize);

            for (uint i = 0; i < fileCount; i++)
            {
                if (bigEndian)
                {
                    fileOffset = MemoryReader.ReadLong(ref buffer, offsetBuffer);
                    fileSize   = MemoryReader.ReadLong(ref buffer, offsetBuffer + 4);
                }
                else
                {
                    fileOffset = MemoryReader.ReadLongBE(ref buffer, offsetBuffer);
                    fileSize   = MemoryReader.ReadLongBE(ref buffer, offsetBuffer + 4);
                }
                string filename = string.Empty;
                filename      = MemoryReader.GetString(ref buffer, offsetBuffer + 8);
                offsetBuffer += (uint)(8 + 1 + filename.Length);
                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
Beispiel #7
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".AWB")
            {
                return(null);
            }

            byte[] filenameBuffer = null;

            FST tmpFST = new FST();

            UInt64 offset     = file.FileStartOffset;
            UInt64 readOffset = offset;

            // check for AFS2 marker
            if (!((fileReader.Read_32bitsBE(readOffset) == 0x41465332) &&
                  (fileReader.Read_32bitsBE(readOffset + 0x04) == 0x01040200)))
            {
                return(null);
            }

            uint fileCount = (uint)fileReader.Read_32bits(readOffset + 0x08);

            readOffset += 0x10;
            readOffset += fileCount * 2;

            uint fileOffset = (uint)fileReader.Read_32bits(readOffset);

            readOffset += 4;

            byte[] buffer = fileReader.Read(readOffset, (fileCount * 4));

            for (uint i = 0; i < fileCount; i++)
            {
                uint nextOffset = MemoryReader.ReadLong(ref buffer, (i * 8));
                uint fileSize;

                uint padding = (fileOffset / 0x10) * 0x10;
                padding -= fileOffset;
                padding += 0x10;

                fileOffset += padding;
                fileSize    = nextOffset;
                fileSize   -= fileOffset;
                string filename = string.Empty;

                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
                fileOffset = nextOffset;
            }

            return(tmpFST);
        }
Beispiel #8
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST tmpFST = new FST();

            if (!((System.IO.Path.GetExtension(file.Filename).ToUpper() == ".PSARC") ||
                  (System.IO.Path.GetExtension(file.Filename).ToUpper() == ".PAC")))
            {
                return(null);
            }

            UInt64 offset = file.FileStartOffset;

            while (offset <= file.FileSize)
            {
                // check for FPAC marker
                if (fileReader.Read_32bitsBE(offset) == 0x46504143)
                {
                    uint sizeofInfo = fileReader.Read_32bits(offset + 0x04);

                    byte[] buffer        = fileReader.Read(offset, sizeofInfo);
                    uint   sizeofFile    = MemoryReader.ReadLong(ref buffer, 0x08);
                    uint   fileCount     = MemoryReader.ReadLong(ref buffer, 0x0c);
                    uint   offsetofIndex = MemoryReader.ReadLong(ref buffer, 0x10);
                    uint   offsetofInfo  = MemoryReader.ReadLong(ref buffer, 0x14);

                    if (fileCount != 0)
                    {
                        uint sizeofOneInfo = 0;
                        sizeofOneInfo = (sizeofInfo - 0x20) / fileCount;

                        for (uint i = 0; i < fileCount; i++)
                        {
                            uint   fileSize   = MemoryReader.ReadLong(ref buffer, (i * sizeofOneInfo) + offsetofInfo + 0x20 + 8);
                            uint   fileOffset = MemoryReader.ReadLong(ref buffer, (i * sizeofOneInfo) + offsetofInfo + 0x20 + 4) + sizeofInfo;
                            string filename   = string.Empty;

                            filename = MemoryReader.GetString(ref buffer, (i * sizeofOneInfo) + 0x20, offsetofInfo);

                            tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
                        }
                    }
                    offset += sizeofFile;
                }
                else
                {
                    offset += 4;
                }
            }
            return(tmpFST);
        }
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for file extension ".POD"
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".POD")
            {
                return(null);
            }

            // check for POD2 marker
            if (fileReader.Read_32bitsBE(offset) != 0x504F4432)
            {
                return(null);
            }

            string archiveName    = fileReader.Read_String(offset + 0x08, 0x50);
            uint   fileCount      = fileReader.Read_32bits(offset + 0x58);
            uint   filenameOffset = 0x60 + (fileCount * 20);
            uint   filenameSize   = fileReader.Read_32bits(offset + 0x68) - filenameOffset;

            byte[] buffer         = fileReader.Read(offset + 0x60, (fileCount * 20));
            byte[] filenameBuffer = fileReader.Read(offset + filenameOffset, filenameSize);

            for (uint i = 0; i < fileCount; i++)
            {
                uint   nameOffset = MemoryReader.ReadLong(ref buffer, (i * 20));
                uint   fileSize   = MemoryReader.ReadLong(ref buffer, (i * 20) + 0x04);
                uint   fileOffset = MemoryReader.ReadLong(ref buffer, (i * 20) + 0x08);
                string filename   = MemoryReader.GetString(ref filenameBuffer, nameOffset);
                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.Filename, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
Beispiel #10
0
        /// <summary>
        /// Test if the current block contains PS2 ADPCM
        /// </summary>
        /// <param name="Reader">StreamReader.IReader Class</param>
        /// <param name="StartOffset">Start offset of the block</param>
        /// <param name="EndOffset">End offset of the block</param>
        /// <returns>True if all the block contains PS2 ADPCM</returns>
        public static bool IsPS2ADPCM(StreamReader.IReader Reader, UInt64 StartOffset, UInt64 EndOffset)
        {
            byte[] buffer = new byte[0x10];
            UInt64 offset = StartOffset;

            do
            {
                buffer  = Reader.Read(offset, 0x10);
                offset += 0x10;
                if ((HINIBBLE(buffer[0]) > 5) || ((LONIBBLE(buffer[0])) > 0xC) || (buffer[1] > 7))
                {
                    return(false);
                }
            } while (offset < EndOffset);
            return(true);
        }
Beispiel #11
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".PAC")
            {
                return(null);
            }

            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for AFS marker
            if (!((fileReader.Read_32bitsBE(offset) == 0x44474b50) && (fileReader.Read_32bitsBE(offset + 4) == 0x00000100)))
            {
                return(null);
            }

            uint fileCount   = (uint)fileReader.Read_32bits(offset + 0x0C);
            uint offsetStart = (uint)fileReader.Read_32bits(offset + 0x10);
            uint fileOffset  = offsetStart;

            for (uint i = 0; i < fileCount; i++)
            {
                byte[] buffer = fileReader.Read(offset + fileOffset, 0x90);
                if (MemoryReader.ReadLongBE(ref buffer, 0) == 0x53415439)
                {
                    fileOffset += 0x90;
                    uint   fileSize = MemoryReader.ReadLong(ref buffer, 0x08);
                    string filename = string.Empty;
                    filename = MemoryReader.GetString(ref buffer, 0x10);

                    tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
                }
                fileOffset += (uint)MemoryReader.ReadLong(ref buffer, 0x08);
            }
            return(tmpFST);
        }
Beispiel #12
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for XAST marker
            if (!((fileReader.Read_32bitsBE(offset) == 0x58415354) && (fileReader.Read_32bitsBE(offset) != 0x00000101)))
            {
                return(null);
            }

            uint fileCount  = (uint)fileReader.Read_32bits(offset + 0x0C);
            uint bufferSize = (uint)fileReader.Read_32bits(offset + 0x14);

            byte[] buffer = fileReader.Read(offset, bufferSize);

            uint buffer_offset = 0x30;

            for (uint i = 0; i < fileCount; i++)
            {
                if (MemoryReader.ReadLong(ref buffer, (i * 48) + buffer_offset) != 0xffffffff)
                {
                    UInt64 fileOffset     = MemoryReader.ReadLong(ref buffer, (i * 48) + buffer_offset + 0x20);
                    uint   fileSize       = MemoryReader.ReadLong(ref buffer, (i * 48) + buffer_offset + 0x10);
                    UInt64 filenameOffset = MemoryReader.ReadLong(ref buffer, (i * 48) + buffer_offset + 0x04);
                    string filename       = string.Empty;

                    filename = MemoryReader.GetString(ref buffer, filenameOffset, 255);

                    tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + fileOffset, fileSize, tmpFST.EmptyDateTime, false));
                }
            }

            return(tmpFST);
        }
Beispiel #13
0
        public FST IsContainer(StreamReader.IReader fileReader, FST.cFile file, int index)
        {
            if (System.IO.Path.GetExtension(file.Filename).ToUpper() != ".IPK")
            {
                return(null);
            }

            FST tmpFST = new FST();

            UInt64 offset = file.FileStartOffset;

            // check for 0x50EC12BA marker
            if (fileReader.Read_32bitsBE(offset) != 0x50EC12BA)
            {
                return(null);
            }

            //string archiveName = fileReader.Read_String(offset + 0x08, 0x50);
            uint fileCount  = (uint)fileReader.Read_32bitsBE(offset + 0x10);
            uint bufferSize = (uint)fileReader.Read_32bitsBE(offset + 0x0C) - 0x30;

            byte[] buffer = fileReader.Read(offset + 0x30, bufferSize);

            uint   buf_offset = 0;
            uint   nameSize   = 0;
            uint   folderSize = 0;
            UInt64 fileOffset = bufferSize + 0x30;

            for (uint i = 0; i < fileCount; i++)
            {
                uint var_temp = MemoryReader.ReadLongBE(ref buffer, buf_offset);
                buf_offset += 4;
                uint fileSizeUncompressed = MemoryReader.ReadLongBE(ref buffer, buf_offset);
                buf_offset += 4;
                uint fileSizeCompressed = MemoryReader.ReadLongBE(ref buffer, buf_offset);
                buf_offset += 4 + 8;
                UInt64 trueFileOffset = MemoryReader.ReadLongLongBE(ref buffer, buf_offset) + fileOffset;
                buf_offset += 8;

                if (var_temp == 2)
                {
                    buf_offset += 8;
                }

                nameSize    = MemoryReader.ReadLongBE(ref buffer, buf_offset);
                buf_offset += 4;
                string filename = string.Empty;
                filename    = MemoryReader.GetString(ref buffer, buf_offset, nameSize);
                buf_offset += nameSize;
                folderSize  = MemoryReader.ReadLongBE(ref buffer, buf_offset);
                buf_offset += 4;
                filename    = MemoryReader.GetString(ref buffer, buf_offset, folderSize) + filename;
                filename    = filename.Replace("/", "\\");
                if (fileSizeCompressed == 0)
                {
                    fileSizeCompressed = fileSizeUncompressed;
                }
                uint fileSize = fileSizeCompressed;
                buf_offset += folderSize + 8;
                tmpFST.FST_File.Add(new FST.cFile(file.SessionID, (uint)index, 0, filename, file.FileOwner, file.FilePath, offset + trueFileOffset, fileSize, tmpFST.EmptyDateTime, false));
            }

            return(tmpFST);
        }
Beispiel #14
0
        public void Init(StreamReader.IReader fileReader, UInt64 offset, ref VGM_Stream vgmStream, bool InitReader, UInt64 fileLength)
        {
            int i;

            char vagID         = (char)fileReader.Read_8Bits(offset + 0x03);
            uint fileVagLength = fileReader.Read_32bitsBE(offset + 0x0c);

            int  channel_count = 1;
            uint interleave    = 0;

            UInt64 loopStart = 0;
            UInt64 loopEnd   = 0;

            bool loop_flag = false;

            switch (vagID)
            {
            case 'i':
                channel_count = 2;
                break;

            case 'V':
                if (fileReader.Read_32bitsBE(offset + 0x20) == 0x53746572)     // vag Stereo
                {
                    channel_count = 2;
                }
                break;

            case 'p':
                if (fileReader.Read_32bitsBE(offset + 0x24) == 0x56414778)
                {
                    loop_flag     = false;
                    channel_count = 2;
                }
                else
                {
                    if (fileReader.Read_32bitsBE(offset + 0x04) <= 0x00000004)
                    {
                        loop_flag     = (fileReader.Read_32bitsBE(offset + 0x14) != 0);
                        channel_count = 1;
                    }
                    else
                    {
                        /* Search for loop in VAG */
                        uint   vagfileLength = fileReader.Read_32bitsBE(offset + 0x0c);
                        UInt64 readOffset    = offset + 0x20;

                        do
                        {
                            readOffset += 0x10;

                            // Loop Start ...
                            if (fileReader.Read_8Bits(readOffset + 0x01) == 0x06)
                            {
                                if (loopStart == 0)
                                {
                                    loopStart = readOffset;
                                }
                            }

                            // Loop End ...
                            if (fileReader.Read_8Bits(readOffset + 0x01) == 0x03)
                            {
                                if (loopEnd == 0)
                                {
                                    loopEnd = readOffset;
                                }
                            }

                            // Loop from end to beginning ...
                            if ((fileReader.Read_8Bits(readOffset + 0x01) == 0x01))
                            {
                                // Check if we have the eof tag after the loop point ...
                                // if so we don't loop, if not present, we loop from end to start ...
                                byte[] vagBuffer = fileReader.Read(readOffset + 0x10, 0x10);
                                if ((vagBuffer[0] != 0) && (vagBuffer[0] != 0x0c))
                                {
                                    if ((vagBuffer[0] == 0x00) && (vagBuffer[0] == 0x07))
                                    {
                                        loopStart = 0x40;
                                        loopEnd   = readOffset;
                                    }
                                }
                            }
                        } while (readOffset < offset + 0x20 + vagfileLength);
                        loop_flag = (loopEnd != 0);
                    }
                }
                break;

            default:
                break;
            }

            /* build the VGMSTREAM */
            VGM_Utils.allocate_vgmStream(ref vgmStream, channel_count, loop_flag);

            /* fill in the vital statistics */
            UInt64 start_offset = offset + 0x30;

            vgmStream.vgmChannelCount = channel_count;
            vgmStream.vgmSampleRate   = (int)fileReader.Read_32bitsBE(offset + 0x10);
            vgmStream.vgmTotalSamples = (int)(fileReader.Read_32bits(offset + 0x04) * 28 / 16);

            vgmStream.vgmLayout = new NoLayout();

            switch (vagID)
            {
            case 'i':     // VAGi
                vgmStream.vgmLayout       = new Interleave();
                vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(0x0C) / 16 * 28;
                interleave   = fileReader.Read_32bitsBE(offset + 0x08);
                start_offset = offset + 0x800;
                break;

            case 'p':              // VAGp
                interleave = 0x10; // used for loop calc

                if (fileReader.Read_32bitsBE(offset + 0x04) == 0x00000004)
                {
                    vgmStream.vgmChannelCount = 2;
                    vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C);

                    if (loop_flag)
                    {
                        vgmStream.vgmLoopStartSample = (int)fileReader.Read_32bitsBE(offset + 0x14);
                        vgmStream.vgmLoopEndSample   = (int)fileReader.Read_32bitsBE(offset + 0x18);
                    }

                    start_offset = offset + 0x80;

                    vgmStream.vgmLayout = new Interleave();

                    // Double VAG Header @ 0x0000 & 0x1000
                    if (fileReader.Read_32bitsBE(offset + 0) == fileReader.Read_32bitsBE(offset + 0x1000))
                    {
                        vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 28;
                        interleave   = 0x1000;
                        start_offset = offset + 0;
                    }
                }
                else
                {
                    if (fileReader.Read_32bitsBE(offset + 0x24) == 0x56414778)
                    {
                        if (fileReader.Read_16bitsBE(offset + fileReader.Read_32bitsBE(offset + 0x0C) + 0x10) != 0x0007)
                        {
                            interleave = 0x8000;
                        }

                        vgmStream.vgmLayout       = new Interleave();
                        vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 14;
                    }
                    else
                    {
                        vgmStream.vgmTotalSamples = (int)fileReader.Read_32bitsBE(offset + 0x0C) / 16 * 28;
                        start_offset = offset + 0x30;
                    }
                }
                break;

            case 'V':     // pGAV
                vgmStream.vgmLayout = new Interleave();
                interleave          = 0x2000;

                // Jak X hack ...
                if (fileReader.Read_32bitsBE(offset + 0x1000) == 0x56414770)
                {
                    interleave = 0x1000;
                }

                vgmStream.vgmSampleRate   = (int)fileReader.Read_32bits(offset + 0x10);
                vgmStream.vgmTotalSamples = (int)fileReader.Read_32bits(offset + 0x0C) / 16 * 14;
                start_offset = offset + 0;
                break;
            }

            vgmStream.vgmDecoder  = new PSX_Decoder();
            vgmStream.vgmLoopFlag = loop_flag;

            if (loop_flag)
            {
                vgmStream.vgmLoopStartSample = (int)(fileReader.Read_32bits(offset + 0x08) * 28 / 16 / vgmStream.vgmChannelCount);
                vgmStream.vgmLoopEndSample   = (int)(fileReader.Read_32bits(offset + 0x04) * 28 / 16);
            }

            vgmStream.vgmInterleaveBlockSize = (int)interleave;

            if (InitReader)
            {
                for (i = 0; i < channel_count; i++)
                {
                    vgmStream.vgmChannel[i].fReader = (StreamReader.IReader)Activator.CreateInstance(fileReader.GetType());;
                    vgmStream.vgmChannel[i].fReader.Open(fileReader.GetFilename());
                    vgmStream.vgmChannel[i].startOffset = vgmStream.vgmChannel[i].currentOffset = start_offset + (UInt64)(vgmStream.vgmInterleaveBlockSize * i);
                }
            }
        }