Exemplo n.º 1
0
        bool IsWsaD2(Stream s)
        {
            if (s.Length < 10)
                return false;

            var start = s.Position;

            numTiles = s.ReadUInt16();
            tileWidth = s.ReadUInt16();
            tileHeight = s.ReadUInt16();
            Delta = s.ReadUInt32();

            offsets = new uint[numTiles + 1];
            for (var i = 0; i <= numTiles; i++)
                offsets[i] = s.ReadUInt32();

            s.Position = start;

            //if (offsets[numTiles] < s.Length)
            //	return false;

            if (offsets[0] == 0)
            {
                numTiles -= 1;
                for (var i = 1; i <= numTiles; i++)
                    offsets[i - 1] = offsets[i];
            }

            return true;
        }
Exemplo n.º 2
0
		public D2kSoundResources(string filename, int priority)
		{
			this.filename = filename;
			this.priority = priority;

			s = GlobalFileSystem.Open(filename);
			try
			{
				filenames = new List<string>();

				var headerLength = s.ReadUInt32();
				while (s.Position < headerLength + 4)
				{
					var name = s.ReadASCIIZ();
					var offset = s.ReadUInt32();
					var length = s.ReadUInt32();

					var hash = PackageEntry.HashFilename(name, PackageHashType.Classic);
					if (!index.ContainsKey(hash))
						index.Add(hash, new PackageEntry(hash, offset, length));

					filenames.Add(name);
				}
			}
			catch
			{
				Dispose();
				throw;
			}
		}
Exemplo n.º 3
0
        public HvaReader(Stream s)
        {
            // Index swaps for transposing a matrix
            var ids = new byte[]{0,4,8,12,1,5,9,13,2,6,10,14};

            s.Seek(16, SeekOrigin.Begin);
            FrameCount = s.ReadUInt32();
            LimbCount = s.ReadUInt32();

            // Skip limb names
            s.Seek(16*LimbCount, SeekOrigin.Current);
            Transforms = new float[16*FrameCount*LimbCount];
            for (var j = 0; j < FrameCount; j++)
                for (var i = 0; i < LimbCount; i++)
            {
                // Convert to column-major matrices and add the final matrix row
                var c = 16*(LimbCount*j + i);
                Transforms[c + 3] = 0;
                Transforms[c + 7] = 0;
                Transforms[c + 11] = 0;
                Transforms[c + 15] = 1;

                for (var k = 0; k < 12; k++)
                    Transforms[c + ids[k]] = s.ReadFloat();
            }
        }
Exemplo n.º 4
0
		public PakFile(string filename, int priority)
		{
			this.filename = filename;
			this.priority = priority;
			index = new Dictionary<string, Entry>();

			stream = GlobalFileSystem.Open(filename);
			try
			{
				index = new Dictionary<string, Entry>();
				var offset = stream.ReadUInt32();
				while (offset != 0)
				{
					var file = stream.ReadASCIIZ();
					var next = stream.ReadUInt32();
					var length = (next == 0 ? (uint)stream.Length : next) - offset;

					// Ignore duplicate files
					if (index.ContainsKey(file))
						continue;

					index.Add(file, new Entry { Offset = offset, Length = length, Filename = file });
					offset = next;
				}
			}
			catch
			{
				Dispose();
				throw;
			}
		}
Exemplo n.º 5
0
        /// <summary>
        /// インスタンスを初期化します。
        /// </summary>
        /// <param name="src">オブジェクト情報を読み取るストリーム。位置はオブジェクトのボディ先頭 ( サイズ情報の直後 ) に設定します。新規作成なら null を指定します。</param>
        public FilePropertiesObject( Stream src )
        {
            if( src == null )
            {
                this.FileId   = Guid.NewGuid();
                this.FileSize = ( ulong )this.Size;
            }
            else
            {
                this.FileId           = src.ReadGuid();
                this.FileSize         = src.ReadUInt64();
                this.CreationDate     = DateTime.FromFileTimeUtc( ( long )src.ReadUInt64() );
                this.DataPacketsCount = src.ReadUInt64();
                this.Duration         = src.ReadUInt64();
                this.SendDuration     = TimeSpan.FromTicks( ( long )src.ReadUInt64() );
                this.Preroll          = src.ReadUInt64();

                // 再生時間から Preroll x 10000 を差し引いたものが、実際の演奏時間となる。
                // この値は複数値からの算出が必要なので、遅延読み込みせずにキャッシュする。
                //
                this.Duration -= ( this.Preroll * FilePropertiesObject.PrerollDelta );

                this.Flags                 = src.ReadUInt32();
                this.MinimumDataPacketSize = src.ReadUInt32();
                this.MaximumDataPacketSize = src.ReadUInt32();
                this.MaximumBitrate        = src.ReadUInt32();
            }
        }
Exemplo n.º 6
0
        public BigFile(FileSystem context, string filename)
        {
            Name = filename;

            s = context.Open(filename);
            try
            {
                if (s.ReadASCII(4) != "BIGF")
                    throw new InvalidDataException("Header is not BIGF");

                // Total archive size.
                s.ReadUInt32();

                var entryCount = s.ReadUInt32();
                if (BitConverter.IsLittleEndian)
                    entryCount = int2.Swap(entryCount);

                // First entry offset? This is apparently bogus for EA's .big files
                // and we don't have to try seeking there since the entries typically start next in EA's .big files.
                s.ReadUInt32();

                for (var i = 0; i < entryCount; i++)
                {
                    var entry = new Entry(s);
                    index.Add(entry.Path, entry);
                }
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemplo n.º 7
0
		public HvaReader(Stream s, string fileName)
		{
			// Index swaps for transposing a matrix
			var ids = new byte[] { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14 };

			s.Seek(16, SeekOrigin.Begin);
			FrameCount = s.ReadUInt32();
			LimbCount = s.ReadUInt32();

			// Skip limb names
			s.Seek(16 * LimbCount, SeekOrigin.Current);
			Transforms = new float[16 * FrameCount * LimbCount];

			var testMatrix = new float[16];
			for (var j = 0; j < FrameCount; j++)
				for (var i = 0; i < LimbCount; i++)
				{
					// Convert to column-major matrices and add the final matrix row
					var c = 16 * (LimbCount * j + i);
					Transforms[c + 3] = 0;
					Transforms[c + 7] = 0;
					Transforms[c + 11] = 0;
					Transforms[c + 15] = 1;

					for (var k = 0; k < 12; k++)
						Transforms[c + ids[k]] = s.ReadFloat();

					Array.Copy(Transforms, 16 * (LimbCount * j + i), testMatrix, 0, 16);
					if (Util.MatrixInverse(testMatrix) == null)
						throw new InvalidDataException(
							"The transformation matrix for HVA file `{0}` section {1} frame {2} is invalid because it is not invertible!"
							.F(fileName, i, j));
				}
		}
        public WwiseSoundbank(Stream s)
        {
            while (s.Position < s.Length)
            {
                SectionId sectionId = (SectionId)s.ReadUInt32();
                uint length = s.ReadUInt32();
                byte[] data = new byte[length];
                s.Read(data, 0, (int)length);

                switch (sectionId)
                {
                    case SectionId.BKHD:
                        BKHDSection bkhd = new BKHDSection(data);
                        Sections.Add(bkhd);
                        break;
                    case SectionId.ENVS:
                        ENVSSection envs = new ENVSSection(data);
                        Sections.Add(envs);
                        break;
                    case SectionId.HIRC:
                        HIRCSection hirc = new HIRCSection(data);
                        Sections.Add(hirc);
                        break;
                    case SectionId.STMG:
                        STMGSection stmg = new STMGSection(data);
                        Sections.Add(stmg);
                        break;
                    default:
                        throw new NotImplementedException("Unknown section: " + sectionId.ToString());
                }
            }
        }
Exemplo n.º 9
0
        public static IPackfile FromStream(Stream stream, bool isStr2)
        {
            stream.Seek(0, SeekOrigin.Begin);
            uint descriptor = stream.ReadUInt32();

            if (descriptor != 0x51890ACE)
                throw new Exception("The input is not a packfile!");

            uint version = stream.ReadUInt32();

            switch (version)
            {
                case 0x04: // Saints Row 2
                    return new Packfiles.Version04.Packfile(stream);

                case 0x06: // Saints Row: The Third
                    return new Packfiles.Version06.Packfile(stream, isStr2);

                case 0x0A: // Saints Row IV & Saints Row: Gat out of Hell
                    return new Packfiles.Version0A.Packfile(stream, isStr2);

                default:
                    throw new Exception(String.Format("Unsupported packfile version: {0:X4}", version));
            }
        }
Exemplo n.º 10
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint strategySetCount = stream.ReadUInt32().SwapEndian();
            uint strategyOptionCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();

            StrategySetList = new List<StrategySet>( (int)strategySetCount );
            for ( uint i = 0; i < strategySetCount; ++i ) {
                StrategySet ss = new StrategySet( stream, refStringStart );
                StrategySetList.Add( ss );
            }
            StrategyOptionList = new List<StrategyOption>( (int)strategyOptionCount );
            for ( uint i = 0; i < strategyOptionCount; ++i ) {
                StrategyOption so = new StrategyOption( stream, refStringStart );
                StrategyOptionList.Add( so );
            }

            StrategyOptionDict = new Dictionary<uint, StrategyOption>( StrategyOptionList.Count );
            foreach ( var option in StrategyOptionList ) {
                StrategyOptionDict.Add( option.InGameID, option );
            }

            return true;
        }
Exemplo n.º 11
0
			public FileGroup(Stream reader, long offset)
			{
				var nameOffset = reader.ReadUInt32();
				/*   unknown  */ reader.ReadBytes(18);
				FirstFile = reader.ReadUInt32();
				LastFile = reader.ReadUInt32();

				reader.Seek(offset + (long)nameOffset, SeekOrigin.Begin);
				Name = reader.ReadASCIIZ();
			}
Exemplo n.º 12
0
        private bool LoadFile( Stream stream, uint textPointerLocationDiff )
        {
            string magic = stream.ReadAscii( 8 );
            uint alwaysSame = stream.ReadUInt32().SwapEndian();
            uint filesize = stream.ReadUInt32().SwapEndian();

            uint lengthSection1 = stream.ReadUInt32().SwapEndian();

            stream.Position = 0x50;
            int textPointerDiffDiff = (int)stream.ReadUInt32().SwapEndian();
            stream.Position = 0x20;
            uint textStart = stream.ReadUInt32().SwapEndian();
            int textPointerDiff = (int)stream.ReadUInt32().SwapEndian() - textPointerDiffDiff;

            EntryList = new List<ScenarioFileEntry>();

            // i wonder what the actual logic behind this is...
            uint textPointersLocation = ( lengthSection1 + 0x80 ).Align( 0x10 ) + textPointerLocationDiff;
            // + 0x1888; // + 0x1B4C // diff of 2C4 // Actually this isn't constant, dammit.

            if ( textStart != textPointersLocation ) {
                stream.Position = textPointersLocation;

                while ( true ) {
                    long loc = stream.Position;
                    stream.DiscardBytes( 8 );
                    uint[] ptrs = new uint[4];
                    ptrs[0] = stream.ReadUInt32().SwapEndian();
                    ptrs[1] = stream.ReadUInt32().SwapEndian();
                    ptrs[2] = stream.ReadUInt32().SwapEndian();
                    ptrs[3] = stream.ReadUInt32().SwapEndian();

                    if ( stream.Position > textStart ) { break; }
                    if ( ptrs.Any( x => x == 0 ) ) { break; }
                    if ( ptrs.Any( x => x + textPointerDiff < textStart ) ) { break; }
                    if ( ptrs.Any( x => x + textPointerDiff >= filesize ) ) { break; }

                    var s = new ScenarioFileEntry();
                    s.Pointer = (uint)loc;
                    stream.Position = ptrs[0] + textPointerDiff;
                    s.JpName = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[1] + textPointerDiff;
                    s.JpText = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[2] + textPointerDiff;
                    s.EnName = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[3] + textPointerDiff;
                    s.EnText = stream.ReadShiftJisNullterm();
                    EntryList.Add( s );

                    stream.Position = loc + 0x18;
                }
            }

            return true;
        }
Exemplo n.º 13
0
        public InstallShieldCABExtractor(FileSystem context, string hdrFilename)
        {
            var fileGroups = new List<FileGroup>();
            var fileGroupOffsets = new List<uint>();

            hdrFile = context.Open(hdrFilename);
            this.context = context;

            // Strips archive number AND file extension
            Name = Regex.Replace(hdrFilename, @"\d*\.[^\.]*$", "");
            var signature = hdrFile.ReadUInt32();

            if (signature != 0x28635349)
                throw new InvalidDataException("Not an Installshield CAB package");

            commonHeader = new CommonHeader(hdrFile);
            cabDescriptor = new CabDescriptor(hdrFile, commonHeader);
            /*    unknown   */ hdrFile.ReadBytes(14);

            for (var i = 0U; i < MaxFileGroupCount; ++i)
                fileGroupOffsets.Add(hdrFile.ReadUInt32());

            hdrFile.Seek(commonHeader.CabDescriptorOffset + cabDescriptor.FileTableOffset, SeekOrigin.Begin);
            directoryTable = new List<uint>();

            for (var i = 0U; i < cabDescriptor.DirectoryCount; ++i)
                directoryTable.Add(hdrFile.ReadUInt32());

            foreach (var offset in fileGroupOffsets)
            {
                var nextOffset = offset;
                while (nextOffset != 0)
                {
                    hdrFile.Seek((long)nextOffset + 4 + commonHeader.CabDescriptorOffset, SeekOrigin.Begin);
                    var descriptorOffset = hdrFile.ReadUInt32();
                    nextOffset = hdrFile.ReadUInt32();
                    hdrFile.Seek(descriptorOffset + commonHeader.CabDescriptorOffset, SeekOrigin.Begin);

                    fileGroups.Add(new FileGroup(hdrFile, commonHeader.CabDescriptorOffset));
                }
            }

            hdrFile.Seek(commonHeader.CabDescriptorOffset + cabDescriptor.FileTableOffset + cabDescriptor.FileTableOffset2, SeekOrigin.Begin);
            foreach (var fileGroup in fileGroups)
            {
                for (var i = fileGroup.FirstFile; i <= fileGroup.LastFile; ++i)
                {
                    AddFileDescriptorToList(i);
                    var fileDescriptor = fileDescriptors[i];
                    var fullFilePath   = "{0}\\{1}\\{2}".F(fileGroup.Name, DirectoryName(fileDescriptor.DirectoryIndex), fileDescriptor.Filename);
                    index.Add(fullFilePath, i);
                }
            }
        }
Exemplo n.º 14
0
        bool IsTmpTD(Stream s)
        {
            var start = s.Position;

            s.Position += 16;
            var a = s.ReadUInt32();
            var b = s.ReadUInt32();

            s.Position = start;
            return a == 0 && b == 0x0D1AFFFF;
        }
Exemplo n.º 15
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint blockCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();

            Blocks = new List<T8BTVABlock>( (int)blockCount );
            for ( uint i = 0; i < blockCount; ++i ) {
                Blocks.Add( new T8BTVABlock( stream, refStringStart ) );
            }

            return true;
        }
Exemplo n.º 16
0
        private static List<ScenarioFileEntry> FindText( Stream stream, uint textStart, bool isUtf8 )
        {
            var list = new List<ScenarioFileEntry>();

            while ( stream.Position < textStart ) {
                uint identifyingBytes = stream.ReadUInt32();
                if ( identifyingBytes == 0x18000C04 ) {
                    uint pos = (uint)stream.Position;

                    uint pointerToText = stream.ReadUInt32().SwapEndian() + textStart;

                    stream.Position = pointerToText;
                    stream.ReadUInt32().SwapEndian();
                    stream.ReadUInt32().SwapEndian();
                    uint jpNamePtr = stream.ReadUInt32().SwapEndian();
                    uint jpTextPtr = stream.ReadUInt32().SwapEndian();
                    uint enNamePtr = stream.ReadUInt32().SwapEndian();
                    uint enTextPtr = stream.ReadUInt32().SwapEndian();
                    stream.Position = jpNamePtr + textStart; string jpName = isUtf8 ? stream.ReadUTF8Nullterm() : stream.ReadShiftJisNullterm();
                    stream.Position = jpTextPtr + textStart; string jpText = isUtf8 ? stream.ReadUTF8Nullterm() : stream.ReadShiftJisNullterm();
                    stream.Position = enNamePtr + textStart; string enName = isUtf8 ? stream.ReadUTF8Nullterm() : stream.ReadShiftJisNullterm();
                    stream.Position = enTextPtr + textStart; string enText = isUtf8 ? stream.ReadUTF8Nullterm() : stream.ReadShiftJisNullterm();

                    var entry = new ScenarioFileEntry() { Pointer = pos, JpName = jpName, EnName = enName, JpText = jpText, EnText = enText };
                    list.Add( entry );

                    stream.Position = pos + 4;
                }
            }

            return list;
        }
Exemplo n.º 17
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint unknown = stream.ReadUInt32().SwapEndian();
            uint titleCount = stream.ReadUInt32().SwapEndian();

            TitleList = new List<Title>( (int)titleCount );
            for ( uint i = 0; i < titleCount; ++i ) {
                Title t = new Title( stream );
                TitleList.Add( t );
            }

            return true;
        }
Exemplo n.º 18
0
        public InstallShieldPackage(FileSystem context, string filename)
        {
            Name = filename;

            s = context.Open(filename);
            try
            {
                // Parse package header
                var signature = s.ReadUInt32();
                if (signature != 0x8C655D13)
                    throw new InvalidDataException("Not an Installshield package");

                s.Position += 8;
                /*var FileCount = */s.ReadUInt16();
                s.Position += 4;
                /*var ArchiveSize = */s.ReadUInt32();
                s.Position += 19;
                var tocAddress = s.ReadInt32();
                s.Position += 4;
                var dirCount = s.ReadUInt16();

                // Parse the directory list
                s.Position = tocAddress;

                // Parse directories
                var directories = new Dictionary<string, uint>();
                for (var i = 0; i < dirCount; i++)
                {
                    // Parse directory header
                    var fileCount = s.ReadUInt16();
                    var chunkSize = s.ReadUInt16();
                    var nameLength = s.ReadUInt16();
                    var dirName = s.ReadASCII(nameLength);

                    // Skip to the end of the chunk
                    s.ReadBytes(chunkSize - nameLength - 6);
                    directories.Add(dirName, fileCount);
                }

                // Parse files
                foreach (var dir in directories)
                    for (var i = 0; i < dir.Value; i++)
                        ParseFile(s, dir.Key);
            }
            catch
            {
                Dispose();
                throw;
            }
        }
Exemplo n.º 19
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint floorInfoCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();

            FloorList = new List<FloorInfo>( (int)floorInfoCount );
            for ( uint i = 0; i < floorInfoCount; ++i ) {
                FloorInfo fi = new FloorInfo( stream, refStringStart );
                FloorList.Add( fi );
            }

            return true;
        }
Exemplo n.º 20
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint infoCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();

            TreasureInfoList = new List<TreasureInfo>( (int)infoCount );
            for ( uint i = 0; i < infoCount; ++i ) {
                TreasureInfo ti = new TreasureInfo( stream, refStringStart );
                TreasureInfoList.Add( ti );
            }

            return true;
        }
Exemplo n.º 21
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint entryCount = stream.ReadUInt32().SwapEndian();
            uint refStringStart = stream.ReadUInt32().SwapEndian();

            GradeShopEntryList = new List<GradeShopEntry>( (int)entryCount );
            for ( uint i = 0; i < entryCount; ++i ) {
                GradeShopEntry e = new GradeShopEntry( stream, refStringStart );
                GradeShopEntryList.Add( e );
            }

            return true;
        }
Exemplo n.º 22
0
			public Entry(Stream s)
			{
				this.s = s;

				offset = s.ReadUInt32();
				size = s.ReadUInt32();
				if (BitConverter.IsLittleEndian)
				{
					offset = int2.Swap(offset);
					size = int2.Swap(size);
				}

				Path = s.ReadASCIIZ();
			}
Exemplo n.º 23
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint unknown = stream.ReadUInt32().SwapEndian();
            uint recipeCount = stream.ReadUInt32().SwapEndian();

            RecipeList = new List<Recipe>( (int)recipeCount );
            for ( uint i = 0; i < recipeCount; ++i ) {
                Recipe r = new Recipe( stream );
                RecipeList.Add( r );
            }

            return true;
        }
Exemplo n.º 24
0
        public InstallShieldCABCompression(Stream header, Dictionary<int, Stream> volumes)
        {
            this.volumes = volumes;

            if (header.ReadUInt32() != 0x28635349)
                throw new InvalidDataException("Not an Installshield CAB package");

            header.Position += 8;
            var cabDescriptorOffset = header.ReadUInt32();
            header.Position = cabDescriptorOffset + 12;
            var cabDescriptor = new CabDescriptor(header);
            header.Position += 14;

            var fileGroupOffsets = new uint[MaxFileGroupCount];
            for (var i = 0; i < MaxFileGroupCount; i++)
                fileGroupOffsets[i] = header.ReadUInt32();

            header.Position = cabDescriptorOffset + cabDescriptor.FileTableOffset;
            var directories = new DirectoryDescriptor[cabDescriptor.DirectoryCount];
            for (var i = 0; i < directories.Length; i++)
                directories[i] = new DirectoryDescriptor(header, cabDescriptorOffset + cabDescriptor.FileTableOffset);

            var fileGroups = new List<FileGroup>();
            foreach (var offset in fileGroupOffsets)
            {
                var nextOffset = offset;
                while (nextOffset != 0)
                {
                    header.Position = cabDescriptorOffset + (long)nextOffset + 4;
                    var descriptorOffset = header.ReadUInt32();
                    nextOffset = header.ReadUInt32();
                    header.Position = cabDescriptorOffset + descriptorOffset;

                    fileGroups.Add(new FileGroup(header, cabDescriptorOffset));
                }
            }

            header.Position = cabDescriptorOffset + cabDescriptor.FileTableOffset + cabDescriptor.FileTableOffset2;
            foreach (var fileGroup in fileGroups)
            {
                for (var i = fileGroup.FirstFile; i <= fileGroup.LastFile; i++)
                {
                    header.Position = cabDescriptorOffset +	cabDescriptor.FileTableOffset + cabDescriptor.FileTableOffset2 + i * 0x57;
                    var file = new FileDescriptor(header, i, cabDescriptorOffset + cabDescriptor.FileTableOffset);
                    var path = "{0}\\{1}\\{2}".F(fileGroup.Name, directories[file.DirectoryIndex].Name, file.Filename);
                    index[path] = file;
                }
            }
        }
Exemplo n.º 25
0
        public MSCabCompression(Stream stream)
        {
            this.stream = stream;

            var signature = stream.ReadASCII(4);
            if (signature != "MSCF")
                throw new InvalidDataException("Not a Microsoft CAB package!");

            stream.Position += 12;
            var filesOffset = stream.ReadUInt32();
            stream.Position += 6;
            var folderCount = stream.ReadUInt16();
            var fileCount = stream.ReadUInt16();
            if (stream.ReadUInt16() != 0)
                throw new InvalidDataException("Only plain packages (without reserved header space or prev/next archives) are supported!");

            stream.Position += 4;

            folders = new CabFolder[folderCount];
            for (var i = 0; i < folderCount; i++)
            {
                folders[i] = new CabFolder(stream);
                if (folders[i].CompressionType != 1)
                    throw new InvalidDataException("Compression type is not supported");
            }

            files = new CabFile[fileCount];
            stream.Seek(filesOffset, SeekOrigin.Begin);
            for (var i = 0; i < fileCount; i++)
                files[i] = new CabFile(stream);
        }
Exemplo n.º 26
0
        public Container(Stream stream)
        {
            UInt16 stringLength = stream.ReadUInt16();
            Name = stream.ReadAsciiString(stringLength);
            ContainerType = stream.ReadUInt8();
            Flags = (ContainerFlags)stream.ReadUInt16();
            PrimitiveCount = stream.ReadUInt16();
            PackfileBaseOffset = stream.ReadUInt32();
            CompressionType = stream.ReadUInt8();
            stringLength = stream.ReadUInt16();
            StubContainerParentName = stream.ReadAsciiString(stringLength);
            Int32 auxDataSize = stream.ReadInt32();
            AuxData = new byte[auxDataSize];
            stream.Read(AuxData, 0, auxDataSize);
            TotalCompressedPackfileReadSize = stream.ReadInt32();

            Primitives = new List<Primitive>();
            PrimitiveSizes = new List<WriteTimeSizes>();

            for (UInt16 i = 0; i < PrimitiveCount; i++)
            {
                var sizes = stream.ReadStruct<WriteTimeSizes>();
                PrimitiveSizes.Add(sizes);
            }

            for (UInt16 i = 0; i < PrimitiveCount; i++)
            {
                Primitive primitive = new Primitive(stream);
                Primitives.Add(primitive);
            }
        }
Exemplo n.º 27
0
        TmpTDFrame[] ParseFrames(Stream s)
        {
            var start = s.Position;
            var width = s.ReadUInt16();
            var height = s.ReadUInt16();
            var size = new Size(width, height);

            s.Position += 8;
            var imgStart = s.ReadUInt32();
            s.Position += 8;
            var indexEnd = s.ReadInt32();
            var indexStart = s.ReadInt32();

            s.Position = indexStart;
            var count = indexEnd - indexStart;
            var tiles = new TmpTDFrame[count];
            var tilesIndex = 0;
            foreach (var b in s.ReadBytes(count))
            {
                if (b != 255)
                {
                    s.Position = imgStart + b * width * height;
                    tiles[tilesIndex++] = new TmpTDFrame(s.ReadBytes(width * height), size);
                }
                else
                    tiles[tilesIndex++] = new TmpTDFrame(null, size);
            }

            s.Position = start;
            return tiles;
        }
Exemplo n.º 28
0
		static bool IsShpTD(Stream s)
		{
			var start = s.Position;

			// First word is the image count
			var imageCount = s.ReadUInt16();
			if (imageCount == 0)
			{
				s.Position = start;
				return false;
			}

			// Last offset should point to the end of file
			var finalOffset = start + 14 + 8 * imageCount;
			if (finalOffset > s.Length)
			{
				s.Position = start;
				return false;
			}

			s.Position = finalOffset;
			var eof = s.ReadUInt32();
			if (eof != s.Length)
			{
				s.Position = start;
				return false;
			}

			// Check the format flag on the first frame
			s.Position = start + 17;
			var b = s.ReadUInt8();

			s.Position = start;
			return b == 0x20 || b == 0x40 || b == 0x80;
		}
Exemplo n.º 29
0
        private bool LoadFile( Stream stream )
        {
            string magic = stream.ReadAscii( 8 );
            uint entrySize = stream.ReadUInt32().SwapEndian();
            uint synopsisCount = stream.ReadUInt32().SwapEndian();
            uint unknown = stream.ReadUInt32().SwapEndian();
            stream.DiscardBytes( 0xC );

            SynopsisList = new List<SynopsisEntry>( (int)synopsisCount );
            for ( uint i = 0; i < synopsisCount; ++i ) {
                SynopsisEntry l = new SynopsisEntry( stream );
                SynopsisList.Add( l );
            }

            return true;
        }
Exemplo n.º 30
0
        public TmpTSReader(Stream s)
        {
            var templateWidth = s.ReadUInt32();
            var templateHeight = s.ReadUInt32();
            var tileWidth = s.ReadInt32();
            var tileHeight = s.ReadInt32();
            var size = new Size(tileWidth, tileHeight);
            var offsets = new uint[templateWidth * templateHeight];
            for (var i = 0; i < offsets.Length; i++)
                offsets[i] = s.ReadUInt32();

            for (var i = 0; i < offsets.Length; i++)
            {
                s.Position = offsets[i];
                tiles.Add(new TmpTSTile(s, size));
            }
        }
Exemplo n.º 31
0
        public static DDSHeader FromStream(Stream stream)
        {
            DDSHeader header = new DDSHeader();

            header.Magic = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            if (header.Magic != 0x20534444)
            {
                throw new Exception("Invalid magic.");
            }
            header.Size = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            if (header.Size != 0x7C)
            {
                throw new Exception("Invalid size.");
            }
            header.Flags             = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Height            = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Width             = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.PitchOrLinearSize = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Depth             = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.MipMapCount       = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1a        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1b        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1c        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1d        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1e        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1f        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1g        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1h        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1i        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1j        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved1k        = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.PixelFormat       = DDSPixelFormat.FromStream(stream);
            header.Caps      = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Caps2     = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Caps3     = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Caps4     = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            header.Reserved2 = stream.ReadUInt32().FromEndian(EndianUtils.Endianness.LittleEndian);
            return(header);
        }
 public static int ReadInt32(this Stream stream)
 {
     return((int)stream.ReadUInt32());
 }
Exemplo n.º 33
0
            public ShpTSFrame(Stream s, Size frameSize)
            {
                var x      = s.ReadUInt16();
                var y      = s.ReadUInt16();
                var width  = s.ReadUInt16();
                var height = s.ReadUInt16();

                // Pad the dimensions to an even number to avoid issues with half-integer offsets
                var dataWidth  = width;
                var dataHeight = height;

                if (dataWidth % 2 == 1)
                {
                    dataWidth += 1;
                }

                if (dataHeight % 2 == 1)
                {
                    dataHeight += 1;
                }

                Offset    = new int2(x + (dataWidth - frameSize.Width) / 2, y + (dataHeight - frameSize.Height) / 2);
                Size      = new Size(dataWidth, dataHeight);
                FrameSize = frameSize;

                Format      = s.ReadUInt8();
                s.Position += 11;
                FileOffset  = s.ReadUInt32();

                if (FileOffset == 0)
                {
                    return;
                }

                // Parse the frame data as we go (but remember to jump back to the header before returning!)
                var start = s.Position;

                s.Position = FileOffset;

                Data = new byte[dataWidth * dataHeight];

                if (Format == 3)
                {
                    // Format 3 provides RLE-zero compressed scanlines
                    for (var j = 0; j < height; j++)
                    {
                        var length = s.ReadUInt16() - 2;
                        RLEZerosCompression.DecodeInto(s.ReadBytes(length), Data, dataWidth * j);
                    }
                }
                else
                {
                    // Format 2 provides uncompressed length-prefixed scanlines
                    // Formats 1 and 0 provide an uncompressed full-width row
                    var length = Format == 2 ? s.ReadUInt16() - 2 : width;
                    for (var j = 0; j < height; j++)
                    {
                        s.ReadBytes(Data, dataWidth * j, length);
                    }
                }

                s.Position = start;
            }
Exemplo n.º 34
0
            public VolumeHeader(Stream stream)
            {
                DataOffset     = stream.ReadUInt32();
                DataOffsetHigh = stream.ReadUInt32();

                FirstFileIndex      = stream.ReadUInt32();
                LastFileIndex       = stream.ReadUInt32();
                FirstFileOffset     = stream.ReadUInt32();
                FirstFileOffsetHigh = stream.ReadUInt32();

                FirstFileSizeExpanded       = stream.ReadUInt32();
                FirstFileSizeExpandedHigh   = stream.ReadUInt32();
                FirstFileSizeCompressed     = stream.ReadUInt32();
                FirstFileSizeCompressedHigh = stream.ReadUInt32();

                LastFileOffset           = stream.ReadUInt32();
                LastFileOffsetHigh       = stream.ReadUInt32();
                LastFileSizeExpanded     = stream.ReadUInt32();
                LastFileSizeExpandedHigh = stream.ReadUInt32();

                LastFileSizeCompressed     = stream.ReadUInt32();
                LastFileSizeCompressedHigh = stream.ReadUInt32();
            }
Exemplo n.º 35
0
        // VQA Frame
        public void DecodeVQFR(Stream s, string parentType = "VQFR")
        {
            // The CBP chunks each contain 1/8th of the full lookup table
            // Annoyingly, the complete table is not applied until the frame
            // *after* the one that contains the 8th chunk.
            // Do we have a set of partial lookup tables ready to apply?
            if (currentChunkBuffer == chunkBufferParts && chunkBufferParts != 0)
            {
                if (!cbpIsCompressed)
                {
                    cbf = (byte[])cbp.Clone();
                }
                else
                {
                    LCWDecodeInto(cbp, cbf);
                }

                chunkBufferOffset = currentChunkBuffer = 0;
            }

            while (true)
            {
                // Chunks are aligned on even bytes; may be padded with a single null
                if (s.Peek() == 0)
                {
                    s.ReadByte();
                }
                var type           = s.ReadASCII(4);
                var subchunkLength = (int)int2.Swap(s.ReadUInt32());

                switch (type)
                {
                // Full frame-modifier
                case "CBFZ":
                    var decodeMode = s.Peek() == 0;
                    s.ReadBytes(fileBuffer, 0, subchunkLength);
                    Array.Clear(cbf, 0, cbf.Length);
                    Array.Clear(cbfBuffer, 0, cbfBuffer.Length);
                    var decodeCount = LCWDecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode);
                    if ((videoFlags & 0x10) == 16)
                    {
                        var p = 0;
                        for (var i = 0; i < decodeCount; i += 2)
                        {
                            var packed = cbfBuffer[i + 1] << 8 | cbfBuffer[i];

                            /* 15      bit      0
                             * 0rrrrrgg gggbbbbb
                             * HI byte  LO byte*/
                            cbf[p++] = (byte)((packed & 0x7C00) >> 7);
                            cbf[p++] = (byte)((packed & 0x3E0) >> 2);
                            cbf[p++] = (byte)((packed & 0x1f) << 3);
                        }
                    }
                    else
                    {
                        cbf = cbfBuffer;
                    }

                    if (parentType == "VQFL")
                    {
                        return;
                    }
                    break;

                case "CBF0":
                    cbf = s.ReadBytes(subchunkLength);
                    break;

                // frame-modifier chunk
                case "CBP0":
                case "CBPZ":
                    var bytes = s.ReadBytes(subchunkLength);
                    bytes.CopyTo(cbp, chunkBufferOffset);
                    chunkBufferOffset += subchunkLength;
                    currentChunkBuffer++;
                    cbpIsCompressed = type == "CBPZ";
                    break;

                // Palette
                case "CPL0":
                    for (var i = 0; i < numColors; i++)
                    {
                        var r = (byte)(s.ReadUInt8() << 2);
                        var g = (byte)(s.ReadUInt8() << 2);
                        var b = (byte)(s.ReadUInt8() << 2);
                        palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
                    }

                    break;

                // Frame data
                case "VPTZ":
                    LCWDecodeInto(s.ReadBytes(subchunkLength), origData);

                    // This is the last subchunk
                    return;

                case "VPRZ":
                    Array.Clear(origData, 0, origData.Length);
                    s.ReadBytes(fileBuffer, 0, subchunkLength);
                    if (fileBuffer[0] != 0)
                    {
                        vtprSize = LCWDecodeInto(fileBuffer, origData);
                    }
                    else
                    {
                        LCWDecodeInto(fileBuffer, origData, 1, true);
                    }
                    return;

                case "VPTR":
                    Array.Clear(origData, 0, origData.Length);
                    s.ReadBytes(origData, 0, subchunkLength);
                    vtprSize = subchunkLength;
                    return;

                default:
                    throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
                }
            }
        }
Exemplo n.º 36
0
 public PackageEntry(Stream s)
 {
     Hash   = s.ReadUInt32();
     Offset = s.ReadUInt32();
     Length = s.ReadUInt32();
 }
Exemplo n.º 37
0
 public static bool ReadValueB32(this Stream stream, Endian endian)
 {
     return(stream.ReadUInt32(endian) != 0);
 }
Exemplo n.º 38
0
        public static unsafe float ReadSingle(this Stream s)
        {
            var ret = s.ReadUInt32();

            return(*((float *)&ret));
        }
Exemplo n.º 39
0
 public CabFolder(Stream stream)
 {
     BlockOffset     = stream.ReadUInt32();
     BlockCount      = stream.ReadUInt16();
     CompressionType = stream.ReadUInt16();
 }
        public static MemoryStream DecompressUDK(Stream raw, long compressionInfoOffset, CompressionType compressionType = CompressionType.None, int NumChunks = 0)
        {
            //PrintCompressDebug(raw, compressionInfoOffset, compressionType, NumChunks);


            raw.JumpTo(compressionInfoOffset);
            if (compressionType == CompressionType.None)
            {
                compressionType = (CompressionType)raw.ReadUInt32();
            }

            if (NumChunks == 0)
            {
                NumChunks = raw.ReadInt32();
            }
            var Chunks          = new List <Chunk>();
            var chunkTableStart = raw.Position;

            //DebugOutput.PrintLn("Reading chunk headers...");
            for (int i = 0; i < NumChunks; i++)
            {
                Chunk c = new Chunk
                {
                    uncompressedOffset = raw.ReadInt32(),
                    uncompressedSize   = raw.ReadInt32(),
                    compressedOffset   = raw.ReadInt32(),
                    compressedSize     = raw.ReadInt32()
                };
                c.Compressed   = new byte[c.compressedSize];
                c.Uncompressed = new byte[c.uncompressedSize];
                //DebugOutput.PrintLn("Chunk " + i + ", compressed size = " + c.compressedSize + ", uncompressed size = " + c.uncompressedSize);
                //DebugOutput.PrintLn("Compressed offset = " + c.compressedOffset + ", uncompressed offset = " + c.uncompressedOffset);
                Chunks.Add(c);
            }


            //DebugOutput.PrintLn("\tRead Chunks...");
            int count = 0;

            for (int i = 0; i < Chunks.Count; i++)
            {
                Chunk chunk = Chunks[i];
                raw.Seek(chunk.compressedOffset, SeekOrigin.Begin);
                raw.Read(chunk.Compressed, 0, chunk.compressedSize);

                ChunkHeader chunkBlockHeader = new ChunkHeader
                {
                    magic            = BitConverter.ToInt32(chunk.Compressed, 0),
                    blocksize        = BitConverter.ToInt32(chunk.Compressed, 4),
                    compressedsize   = BitConverter.ToInt32(chunk.Compressed, 8),
                    uncompressedsize = BitConverter.ToInt32(chunk.Compressed, 12)
                };



                if (chunkBlockHeader.magic != -1641380927)
                {
                    throw new FormatException("Chunk magic number incorrect");
                }
                //DebugOutput.PrintLn("Chunkheader read: Magic = " + h.magic + ", Blocksize = " + h.blocksize + ", Compressed Size = " + h.compressedsize + ", Uncompressed size = " + h.uncompressedsize);
                int pos        = 16;
                int blockCount = (chunkBlockHeader.uncompressedsize % chunkBlockHeader.blocksize == 0)
                    ? chunkBlockHeader.uncompressedsize / chunkBlockHeader.blocksize : chunkBlockHeader.uncompressedsize / chunkBlockHeader.blocksize + 1;

                #region Sanity checking from April 29 2020
                //int sizeOfChunk = 16;
                //int sizeOfChunkBlock = 8;
                //int maxBlockSizeMEM = 0x20000; // 128KB
                //int sanityCheckMEM = chunkBlockHeader.compressedsize + sizeOfChunk + sizeOfChunkBlock * blockCount;

                //if (sanityCheckMEM != chunk.compressedSize)
                //{
                //    Debug.WriteLine($" >> SANITY CHECK {i} FAILED. CHUNKCOMPSIZE: {chunk.compressedSize}, MEM Expected Chunk Comp Size: {sanityCheckMEM}, Difference: {sanityCheckMEM - chunk.compressedSize}");
                //}
                //else
                //{
                //    Debug.WriteLine($" >> SANITY CHECK {i} OK. CHUNKCOMPSIZE: {chunk.compressedSize}, MEM Expected Chunk Comp Size: {sanityCheckMEM}, Difference: {sanityCheckMEM - chunk.compressedSize}");
                //}
                #endregion

                var BlockList = new List <Block>();
                //DebugOutput.PrintLn("\t\t" + count + " Read Blockheaders...");
                for (int j = 0; j < blockCount; j++)
                {
                    Block b = new Block
                    {
                        compressedsize   = BitConverter.ToInt32(chunk.Compressed, pos),
                        uncompressedsize = BitConverter.ToInt32(chunk.Compressed, pos + 4)
                    };
                    //DebugOutput.PrintLn("Block " + j + ", compressed size = " + b.compressedsize + ", uncompressed size = " + b.uncompressedsize);
                    pos += 8;
                    BlockList.Add(b);
                }
                int outpos   = 0;
                int blocknum = 0;
                //DebugOutput.PrintLn("\t\t" + count + " Read and decompress Blocks...");
                foreach (Block b in BlockList)
                {
                    //Debug.WriteLine("Decompressing block " + blocknum);
                    var datain  = new byte[b.compressedsize];
                    var dataout = new byte[b.uncompressedsize];
                    for (int j = 0; j < b.compressedsize; j++)
                    {
                        datain[j] = chunk.Compressed[pos + j];
                    }
                    pos += b.compressedsize;

                    switch (compressionType)
                    {
                    case CompressionType.LZO:
                    {
                        if (
                            LZO2.Decompress(datain, (uint)datain.Length, dataout) != b.uncompressedsize)
                        {
                            throw new Exception("LZO decompression failed!");
                        }
                        break;
                    }

                    case CompressionType.Zlib:
                    {
                        if (ZlibHelper.Zlib.Decompress(datain, (uint)datain.Length, dataout) != b.uncompressedsize)
                        {
                            throw new Exception("Zlib decompression failed!");
                        }
                        break;
                    }

                    /* WII U
                     * case CompressionType.LZMA:
                     *  dataout = LZMA.Decompress(datain, (uint)b.uncompressedsize);
                     *  if (dataout.Length != b.uncompressedsize)
                     *      throw new Exception("LZMA decompression failed!");
                     *  break;
                     */
                    default:
                        throw new Exception("Unknown compression type for this package.");
                    }
                    for (int j = 0; j < b.uncompressedsize; j++)
                    {
                        chunk.Uncompressed[outpos + j] = dataout[j];
                    }
                    outpos += b.uncompressedsize;
                    blocknum++;
                }
                chunk.header = chunkBlockHeader;
                chunk.blocks = BlockList;
                count++;
                Chunks[i] = chunk;
            }

            MemoryStream result = new MemoryStream();
            foreach (Chunk c in Chunks)
            {
                result.Seek(c.uncompressedOffset, SeekOrigin.Begin);
                result.WriteFromBuffer(c.Uncompressed);
            }

            return(result);
        }
Exemplo n.º 41
0
        public void DIVAReader(bool ToArray = false)
        {
            if (File.Exists(file + ".diva"))
            {
                Data = new DIVAFile();
                Stream reader = File.OpenReader(file + ".diva");

                if (reader.ReadString(0x04) == "DIVA")
                {
                    reader.ReadInt32();
                    Data.Size         = reader.ReadUInt32();
                    Data.SampleRate   = reader.ReadUInt32();
                    Data.SamplesCount = reader.ReadUInt32();
                    reader.ReadInt64();
                    Data.Channels = reader.ReadUInt16();
                    reader.ReadUInt16();
                    Data.Name = reader.ReadString(0x20);

                    Stream writer = File.OpenWriter();
                    if (!ToArray)
                    {
                        writer = File.OpenWriter(file + ".wav", true);
                    }
                    writer.LongPosition = 0x2C;

                    byte    value        = 0;
                    int[]   current      = new int[Data.Channels];
                    int[]   currentclamp = new int[Data.Channels];
                    sbyte[] stepindex    = new sbyte[Data.Channels];
                    float   f;

                    int *  currentPtr      = current.GetPtr();
                    int *  currentclampPtr = currentclamp.GetPtr();
                    sbyte *stepindexPtr    = stepindex.GetPtr();

                    for (i = 0; i < Data.SamplesCount; i++)
                    {
                        for (c = 0; c < Data.Channels; c++)
                        {
                            value = reader.ReadHalfByte();
                            IMADecoder(value, ref currentPtr[c], ref currentclampPtr[c], ref stepindexPtr[c]);
                            f = (float)(currentPtr[c] / 32768.0);
                            writer.Write(f);
                        }
                    }

                    WAV.Header Header = new WAV.Header
                    {
                        Bytes      = 4, Channels = Data.Channels, Format = 3,
                        SampleRate = Data.SampleRate, Size = Data.SamplesCount * Data.Channels * 4
                    };
                    writer.Write(Header, 0);
                    if (ToArray)
                    {
                        Data.Data = writer.ToArray();
                    }
                    writer.Close();
                }
                reader.Close();
            }
        }
Exemplo n.º 42
0
        bool IsIcnD2(Stream s)
        {
            if (s.Length < 0x20)
            {
                return(false);
            }

            var start = s.Position;

            s.Position = 0x18;
            if (s.ReadASCII(4) != "SSET")
            {
                s.Position = start;
                return(false);
            }

            ssetLength  = int2.Swap(s.ReadUInt32()) - 8;
            s.Position += 3;
            ssetOffset  = 0x18 + 16;
            if (s.Length < ssetOffset + ssetLength)
            {
                s.Position = start;
                return(false);
            }

            s.Position = ssetOffset + ssetLength;
            if (s.ReadASCII(4) != "RPAL")
            {
                s.Position = start;
                return(false);
            }

            rpalLength = int2.Swap(s.ReadUInt32());
            rpalOffset = ssetOffset + ssetLength + 8;
            if (s.Length < rpalOffset + rpalLength)
            {
                s.Position = start;
                return(false);
            }

            s.Position = rpalOffset + rpalLength;
            if (s.ReadASCII(4) != "RTBL")
            {
                s.Position = start;
                return(false);
            }

            rtblLength = int2.Swap(s.ReadUInt32());
            rtblOffset = rpalOffset + rpalLength + 8;

            if (s.Length < rtblOffset + rtblLength)
            {
                s.Position = start;
                return(false);
            }

            numTiles = ssetLength / TileSize;

            if (rtblLength < numTiles)
            {
                s.Position = start;
                return(false);
            }

            s.Position = start;
            return(true);
        }
Exemplo n.º 43
0
            public TmpTSFrame(Stream s, Size size, int u, int v)
            {
                if (s.Position != 0)
                {
                    Size = size;

                    // Skip unnecessary header data
                    s.Position += 20;

                    // Extra data is specified relative to the top-left of the template
                    var extraX      = s.ReadInt32() - (u - v) * size.Width / 2;
                    var extraY      = s.ReadInt32() - (u + v) * size.Height / 2;
                    var extraWidth  = s.ReadInt32();
                    var extraHeight = s.ReadInt32();
                    var flags       = s.ReadUInt32();

                    var bounds = new Rectangle(0, 0, size.Width, size.Height);
                    if ((flags & 0x01) != 0)
                    {
                        var extraBounds = new Rectangle(extraX, extraY, extraWidth, extraHeight);
                        bounds = Rectangle.Union(bounds, extraBounds);

                        Offset = new float2(bounds.X + 0.5f * (bounds.Width - size.Width), bounds.Y + 0.5f * (bounds.Height - size.Height));
                        Size   = new Size(bounds.Width, bounds.Height);
                    }

                    // Skip unnecessary header data
                    s.Position += 12;

                    Data      = new byte[bounds.Width * bounds.Height];
                    DepthData = new byte[bounds.Width * bounds.Height];

                    UnpackTileData(s, Data, size, bounds);
                    UnpackTileData(s, DepthData, size, bounds);

                    if ((flags & 0x01) == 0)
                    {
                        return;
                    }

                    // Load extra data (cliff faces, etc)
                    for (var j = 0; j < extraHeight; j++)
                    {
                        var start = (j + extraY - bounds.Y) * bounds.Width + extraX - bounds.X;
                        for (var i = 0; i < extraWidth; i++)
                        {
                            var extra = s.ReadUInt8();
                            if (extra != 0)
                            {
                                Data[start + i] = extra;
                            }
                        }
                    }

                    // Extra data depth
                    for (var j = 0; j < extraHeight; j++)
                    {
                        var start = (j + extraY - bounds.Y) * bounds.Width + extraX - bounds.X;
                        for (var i = 0; i < extraWidth; i++)
                        {
                            var extra = s.ReadUInt8();

                            // XCC source indicates that there are only 32 valid values
                            if (extra < 32)
                            {
                                DepthData[start + i] = extra;
                            }
                        }
                    }
                }
                else
                {
                    Data = new byte[0];
                }
            }
Exemplo n.º 44
0
        private void loadHeader(Stream stream)
        {
            uint tag = stream.ReadUInt32();

            if (tag != SfarTag)
            {
                throw new Exception("Wrong SFAR tag");
            }
            uint sfarVersion = stream.ReadUInt32();

            if (sfarVersion != SfarVersion)
            {
                throw new Exception("Wrong SFAR version");
            }

            uint dataOffset    = stream.ReadUInt32();
            uint entriesOffset = stream.ReadUInt32();

            filesCount = stream.ReadUInt32();
            uint sizesArrayOffset = stream.ReadUInt32();

            maxBlockSize = stream.ReadUInt32();
            uint compressionTag = stream.ReadUInt32();

            if (compressionTag != LZMATag)
            {
                throw new Exception("Not LZMA compression for SFAR file");
            }

            uint numBlockSizes = 0;

            stream.JumpTo(entriesOffset);
            filesList = new List <FileEntry>();
            for (int i = 0; i < filesCount; i++)
            {
                FileEntry file = new FileEntry();
                file.filenameHash = stream.ReadToBuffer(16);
                file.compressedBlockSizesIndex = stream.ReadInt32();
                file.uncomprSize  = stream.ReadUInt32();
                file.uncomprSize |= (long)stream.ReadByte() << 32;
                file.dataOffset   = stream.ReadUInt32();
                file.dataOffset  |= (long)stream.ReadByte() << 32;
                file.numBlocks    = (uint)((file.uncomprSize + maxBlockSize - 1) / maxBlockSize);
                filesList.Add(file);
                numBlockSizes += file.numBlocks;
            }

            stream.JumpTo(sizesArrayOffset);
            blockSizes = new List <ushort>();
            for (int i = 0; i < numBlockSizes; i++)
            {
                blockSizes.Add(stream.ReadUInt16());
            }

            filenamesIndex = -1;
            for (int i = 0; i < filesCount; i++)
            {
                if (StructuralComparisons.StructuralEqualityComparer.Equals(filesList[i].filenameHash, FileListHash))
                {
                    stream.JumpTo(filesList[i].dataOffset);
                    int    compressedBlockSize = blockSizes[filesList[i].compressedBlockSizesIndex];
                    byte[] inBuf  = stream.ReadToBuffer(compressedBlockSize);
                    byte[] outBuf = SevenZipHelper.LZMA.Decompress(inBuf, (uint)filesList[i].uncomprSize);
                    if (outBuf.Length == 0)
                    {
                        throw new Exception();
                    }
                    StreamReader filenamesStream = new StreamReader(new MemoryStream(outBuf));
                    while (filenamesStream.EndOfStream == false)
                    {
                        string name = filenamesStream.ReadLine();
                        byte[] hash = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(name.ToLowerInvariant()));
                        for (int l = 0; l < filesCount; l++)
                        {
                            if (StructuralComparisons.StructuralEqualityComparer.Equals(filesList[l].filenameHash, hash))
                            {
                                FileEntry f = filesList[l];
                                f.filenamePath = name;
                                filesList[l]   = f;
                            }
                        }
                    }
                    filenamesIndex = i;
                    break;
                }
            }
            if (filenamesIndex == -1)
            {
                throw new Exception("filenames entry not found");
            }
        }
Exemplo n.º 45
0
        void CollectAudioData()
        {
            var audio1     = new MemoryStream();         // left channel / mono
            var audio2     = new MemoryStream();         // right channel
            var adpcmIndex = 0;
            var compressed = false;

            for (var i = 0; i < frames; i++)
            {
                stream.Seek(offsets[i], SeekOrigin.Begin);
                var end = (i < frames - 1) ? offsets[i + 1] : stream.Length;

                while (stream.Position < end)
                {
                    var type = stream.ReadASCII(4);
                    if (type == "SN2J")
                    {
                        var jmp = int2.Swap(stream.ReadUInt32());
                        stream.Seek(jmp, SeekOrigin.Current);
                        type = stream.ReadASCII(4);
                    }

                    var length = int2.Swap(stream.ReadUInt32());

                    switch (type)
                    {
                    case "SND0":
                    case "SND2":
                        if (audioChannels == 0)
                        {
                            throw new NotSupportedException();
                        }
                        else if (audioChannels == 1)
                        {
                            var rawAudio = stream.ReadBytes((int)length);
                            audio1.WriteArray(rawAudio);
                        }
                        else
                        {
                            var rawAudio = stream.ReadBytes((int)length / 2);
                            audio1.WriteArray(rawAudio);
                            rawAudio = stream.ReadBytes((int)length / 2);
                            audio2.WriteArray(rawAudio);
                            if (length % 2 != 0)
                            {
                                stream.ReadBytes(2);
                            }
                        }

                        compressed = type == "SND2";
                        break;

                    default:
                        if (length + stream.Position > stream.Length)
                        {
                            throw new NotSupportedException("Vqa uses unknown Subtype: {0}".F(type));
                        }
                        stream.ReadBytes((int)length);
                        break;
                    }

                    // Chunks are aligned on even bytes; advance by a byte if the next one is null
                    if (stream.Peek() == 0)
                    {
                        stream.ReadByte();
                    }
                }
            }

            if (audioChannels == 1)
            {
                audioData = compressed ? ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex) : audio1.ToArray();
            }
            else
            {
                byte[] leftData, rightData;
                if (!compressed)
                {
                    leftData  = audio1.ToArray();
                    rightData = audio2.ToArray();
                }
                else
                {
                    adpcmIndex = 0;
                    leftData   = ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex);
                    adpcmIndex = 0;
                    rightData  = ImaAdpcmReader.LoadImaAdpcmSound(audio2.ToArray(), ref adpcmIndex);
                }

                audioData = new byte[rightData.Length + leftData.Length];
                var rightIndex = 0;
                var leftIndex  = 0;
                for (var i = 0; i < audioData.Length;)
                {
                    audioData[i++] = leftData[leftIndex++];
                    audioData[i++] = leftData[leftIndex++];
                    audioData[i++] = rightData[rightIndex++];
                    audioData[i++] = rightData[rightIndex++];
                }
            }

            hasAudio = audioData.Length > 0;
        }
Exemplo n.º 46
0
        // VQA Frame
        public void DecodeVQFR(Stream s, string parentType = "VQFR")
        {
            while (true)
            {
                // Chunks are aligned on even bytes; may be padded with a single null
                if (s.Peek() == 0)
                {
                    s.ReadByte();
                }
                var type           = s.ReadASCII(4);
                var subchunkLength = (int)int2.Swap(s.ReadUInt32());

                switch (type)
                {
                // Full frame-modifier
                case "CBFZ":
                    var decodeMode = s.Peek() == 0;
                    s.ReadBytes(fileBuffer, 0, subchunkLength);
                    Array.Clear(cbf, 0, cbf.Length);
                    Array.Clear(cbfBuffer, 0, cbfBuffer.Length);
                    var decodeCount = 0;
                    decodeCount = Format80.DecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode);
                    if ((videoFlags & 0x10) == 16)
                    {
                        var p = 0;
                        for (var i = 0; i < decodeCount; i += 2)
                        {
                            var packed = cbfBuffer[i + 1] << 8 | cbfBuffer[i];

                            /* 15      bit      0
                             * 0rrrrrgg gggbbbbb
                             * HI byte  LO byte*/
                            cbf[p++] = (byte)((packed & 0x7C00) >> 7);
                            cbf[p++] = (byte)((packed & 0x3E0) >> 2);
                            cbf[p++] = (byte)((packed & 0x1f) << 3);
                        }
                    }
                    else
                    {
                        cbf = cbfBuffer;
                    }

                    if (parentType == "VQFL")
                    {
                        return;
                    }
                    break;

                case "CBF0":
                    cbf = s.ReadBytes(subchunkLength);
                    break;

                // frame-modifier chunk
                case "CBP0":
                case "CBPZ":
                    // Partial buffer is full; dump and recreate
                    if (currentChunkBuffer == chunkBufferParts)
                    {
                        if (type == "CBP0")
                        {
                            cbf = (byte[])cbp.Clone();
                        }
                        else
                        {
                            Format80.DecodeInto(cbp, cbf);
                        }

                        chunkBufferOffset = currentChunkBuffer = 0;
                    }

                    var bytes = s.ReadBytes(subchunkLength);
                    bytes.CopyTo(cbp, chunkBufferOffset);
                    chunkBufferOffset += subchunkLength;
                    currentChunkBuffer++;
                    break;

                // Palette
                case "CPL0":
                    for (var i = 0; i < numColors; i++)
                    {
                        var r = (byte)(s.ReadUInt8() << 2);
                        var g = (byte)(s.ReadUInt8() << 2);
                        var b = (byte)(s.ReadUInt8() << 2);
                        palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
                    }

                    break;

                // Frame data
                case "VPTZ":
                    Format80.DecodeInto(s.ReadBytes(subchunkLength), origData);

                    // This is the last subchunk
                    return;

                case "VPRZ":
                    Array.Clear(origData, 0, origData.Length);
                    s.ReadBytes(fileBuffer, 0, subchunkLength);
                    if (fileBuffer[0] != 0)
                    {
                        vtprSize = Format80.DecodeInto(fileBuffer, origData);
                    }
                    else
                    {
                        Format80.DecodeInto(fileBuffer, origData, 1, true);
                    }
                    return;

                case "VPTR":
                    Array.Clear(origData, 0, origData.Length);
                    s.ReadBytes(origData, 0, subchunkLength);
                    vtprSize = subchunkLength;
                    return;

                default:
                    throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
                }
            }
        }
Exemplo n.º 47
0
        public VqaReader(Stream stream)
        {
            this.stream = stream;

            // Decode FORM chunk
            if (stream.ReadASCII(4) != "FORM")
            {
                throw new InvalidDataException("Invalid vqa (invalid FORM section)");
            }
            /*var length = */ stream.ReadUInt32();

            if (stream.ReadASCII(8) != "WVQAVQHD")
            {
                throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
            }
            /*var length2 = */ stream.ReadUInt32();

            /*var version = */ stream.ReadUInt16();
            videoFlags = stream.ReadUInt16();
            frames     = stream.ReadUInt16();
            width      = stream.ReadUInt16();
            height     = stream.ReadUInt16();

            blockWidth       = stream.ReadUInt8();
            blockHeight      = stream.ReadUInt8();
            framerate        = stream.ReadUInt8();
            chunkBufferParts = stream.ReadUInt8();
            blocks           = new int2(width / blockWidth, height / blockHeight);

            numColors = stream.ReadUInt16();
            /*var maxBlocks = */ stream.ReadUInt16();
            /*var unknown1 = */ stream.ReadUInt16();
            /*var unknown2 = */ stream.ReadUInt32();

            // Audio
            sampleRate    = stream.ReadUInt16();
            audioChannels = stream.ReadByte();
            sampleBits    = stream.ReadByte();

            /*var unknown3 =*/ stream.ReadUInt32();
            /*var unknown4 =*/ stream.ReadUInt16();
            /*maxCbfzSize =*/ stream.ReadUInt32();            // Unreliable

            /*var unknown5 =*/ stream.ReadUInt32();

            var frameSize = Exts.NextPowerOf2(Math.Max(width, height));

            if (IsHqVqa)
            {
                cbfBuffer = new byte[maxCbfzSize];
                cbf       = new byte[maxCbfzSize * 3];
                origData  = new byte[maxCbfzSize];
            }
            else
            {
                cbfBuffer = new byte[width * height];
                cbf       = new byte[width * height];
                cbp       = new byte[width * height];
                origData  = new byte[2 * blocks.X * blocks.Y];
            }

            palette   = new uint[numColors];
            frameData = new uint[frameSize, frameSize];
            var type = stream.ReadASCII(4);

            while (type != "FINF")
            {
                // Sub type is a file tag
                if (type[3] == 'F')
                {
                    var jmp = int2.Swap(stream.ReadUInt32());
                    stream.Seek(jmp, SeekOrigin.Current);
                    type = stream.ReadASCII(4);
                }
                else
                {
                    throw new NotSupportedException("Vqa uses unknown Subtype: {0}".F(type));
                }
            }

            /*var length = */ stream.ReadUInt16();
            /*var unknown4 = */ stream.ReadUInt16();

            // Frame offsets
            offsets = new uint[frames];
            for (var i = 0; i < frames; i++)
            {
                offsets[i] = stream.ReadUInt32();
                if (offsets[i] > 0x40000000)
                {
                    offsets[i] -= 0x40000000;
                }
                offsets[i] <<= 1;
            }

            CollectAudioData();

            Reset();
        }
        public void Deserialize(Stream input)
        {
            var magic = input.ReadUInt32();

            if (magic != 0x434F4E44 && magic.Swap() != 0x434F4E44)
            {
                throw new FormatException();
            }

            var endian = magic == 0x434F4E44 ? ByteOrder.LittleEndian : ByteOrder.BigEndian;

            var version = input.ReadUInt32(endian);

            if (version != 1)
            {
                throw new FormatException();
            }

            Version = version;

            var unknown08 = input.ReadUInt16(endian);
            var count     = input.ReadUInt16(endian);

            var ids     = new int[count];
            var offsets = new uint[count];

            for (ushort i = 0; i < count; i++)
            {
                ids[i]     = input.ReadInt32(endian);
                offsets[i] = input.ReadUInt32(endian);
            }

            var sortedOffsets = offsets
                                .OrderBy(o => o)
                                .Distinct()
                                .ToArray();

            _Buffers.Clear();

            for (var i = 0; i < sortedOffsets.Length; i++)
            {
                var offset = sortedOffsets[i];

                if (offset == 0)
                {
                    continue;
                }

                var nextOffset = i + 1 < sortedOffsets.Length
                                        ? sortedOffsets[i + 1]
                                        : input.Length;

                input.Seek(offset, SeekOrigin.Begin);

                var length = (int)(nextOffset - offset);

                var bytes = input.ReadBytes(length);

                _Buffers.Add(offset, bytes);
            }

            _Conditionals.Clear();

            for (var i = 0; i < count; i++)
            {
                _Conditionals.Add(ids[i], offsets[i]);
            }

            ByteOrder = endian;
        }
Exemplo n.º 49
0
            void SetVolume(int newVolume)
            {
                currentVolumeID = newVolume;
                if (!volumes.TryGetValue(currentVolumeID, out currentVolume))
                {
                    throw new FileNotFoundException("Volume {0} is not available".F(currentVolumeID));
                }

                currentVolume.Position = 0;
                if (currentVolume.ReadUInt32() != 0x28635349)
                {
                    throw new InvalidDataException("Not an Installshield CAB package");
                }

                uint fileOffset;

                if (file.Flags.HasFlag(CABFlags.FileSplit))
                {
                    currentVolume.Position += CommonHeader.Size;
                    var head = new VolumeHeader(currentVolume);
                    if (file.Index == head.LastFileIndex)
                    {
                        if (file.Flags.HasFlag(CABFlags.FileCompressed))
                        {
                            remainingInArchive = head.LastFileSizeCompressed;
                        }
                        else
                        {
                            remainingInArchive = head.LastFileSizeExpanded;
                        }

                        fileOffset = head.LastFileOffset;
                    }
                    else if (file.Index == head.FirstFileIndex)
                    {
                        if (file.Flags.HasFlag(CABFlags.FileCompressed))
                        {
                            remainingInArchive = head.FirstFileSizeCompressed;
                        }
                        else
                        {
                            remainingInArchive = head.FirstFileSizeExpanded;
                        }

                        fileOffset = head.FirstFileOffset;
                    }
                    else
                    {
                        throw new InvalidDataException("Cannot Resolve Remaining Stream");
                    }
                }
                else
                {
                    if (file.Flags.HasFlag(CABFlags.FileCompressed))
                    {
                        remainingInArchive = file.CompressedSize;
                    }
                    else
                    {
                        remainingInArchive = file.ExpandedSize;
                    }

                    fileOffset = file.DataOffset;
                }

                currentVolume.Position = fileOffset;
            }
Exemplo n.º 50
0
        public VqaVideo(Stream stream, bool useFramePadding)
        {
            this.stream = stream;

            // Decode FORM chunk
            if (stream.ReadASCII(4) != "FORM")
            {
                throw new InvalidDataException("Invalid vqa (invalid FORM section)");
            }
            /*var length = */ stream.ReadUInt32();

            if (stream.ReadASCII(8) != "WVQAVQHD")
            {
                throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
            }
            /*var length2 = */ stream.ReadUInt32();

            /*var version = */ stream.ReadUInt16();
            videoFlags = stream.ReadUInt16();
            FrameCount = stream.ReadUInt16();
            Width      = stream.ReadUInt16();
            Height     = stream.ReadUInt16();

            blockWidth       = stream.ReadUInt8();
            blockHeight      = stream.ReadUInt8();
            Framerate        = stream.ReadUInt8();
            chunkBufferParts = stream.ReadUInt8();
            blocks           = new int2(Width / blockWidth, Height / blockHeight);

            numColors = stream.ReadUInt16();
            /*var maxBlocks = */ stream.ReadUInt16();
            /*var unknown1 = */ stream.ReadUInt16();
            /*var unknown2 = */ stream.ReadUInt32();

            // Audio
            SampleRate    = stream.ReadUInt16();
            AudioChannels = stream.ReadByte();
            SampleBits    = stream.ReadByte();

            /*var unknown3 =*/ stream.ReadUInt32();
            /*var unknown4 =*/ stream.ReadUInt16();
            /*maxCbfzSize =*/ stream.ReadUInt32();            // Unreliable

            /*var unknown5 =*/ stream.ReadUInt32();

            if (IsHqVqa)
            {
                cbfBuffer = new byte[maxCbfzSize];
                cbf       = new byte[maxCbfzSize * 3];
                origData  = new byte[maxCbfzSize];
            }
            else
            {
                cbfBuffer = new byte[Width * Height];
                cbf       = new byte[Width * Height];
                cbp       = new byte[Width * Height];
                origData  = new byte[2 * blocks.X * blocks.Y];
            }

            paletteBytes = new byte[numColors * 4];
            var type = stream.ReadASCII(4);

            while (type != "FINF")
            {
                // Sub type is a file tag
                if (type[3] == 'F')
                {
                    var jmp = int2.Swap(stream.ReadUInt32());
                    stream.Seek(jmp, SeekOrigin.Current);
                    type = stream.ReadASCII(4);
                }
                else
                {
                    throw new NotSupportedException($"Vqa uses unknown Subtype: {type}");
                }
            }

            /*var length = */ stream.ReadUInt16();
            /*var unknown4 = */ stream.ReadUInt16();

            // Frame offsets
            offsets = new uint[FrameCount];
            for (var i = 0; i < FrameCount; i++)
            {
                offsets[i] = stream.ReadUInt32();
                if (offsets[i] > 0x40000000)
                {
                    offsets[i] -= 0x40000000;
                }
                offsets[i] <<= 1;
            }

            CollectAudioData();

            if (useFramePadding)
            {
                var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));
                CurrentFrameData = new byte[frameSize * frameSize * 4];
                totalFrameWidth  = (ushort)frameSize;
            }
            else
            {
                CurrentFrameData = new byte[Width * Height * 4];
                totalFrameWidth  = Width;
            }

            Reset();
        }
Exemplo n.º 51
0
        private bool LoadFile(Stream stream, uint textPointerLocationDiff)
        {
            string magic      = stream.ReadAscii(8);
            uint   alwaysSame = stream.ReadUInt32().SwapEndian();
            uint   filesize   = stream.ReadUInt32().SwapEndian();

            uint lengthSection1 = stream.ReadUInt32().SwapEndian();

            stream.Position = 0x50;
            int textPointerDiffDiff = (int)stream.ReadUInt32().SwapEndian();

            stream.Position = 0x20;
            uint textStart       = stream.ReadUInt32().SwapEndian();
            int  textPointerDiff = (int)stream.ReadUInt32().SwapEndian() - textPointerDiffDiff;

            EntryList = new List <ScenarioFileEntry>();

            // i wonder what the actual logic behind this is...
            uint textPointersLocation = (lengthSection1 + 0x80).Align(0x10) + textPointerLocationDiff;

            // + 0x1888; // + 0x1B4C // diff of 2C4 // Actually this isn't constant, dammit.

            if (textStart != textPointersLocation)
            {
                stream.Position = textPointersLocation;

                while (true)
                {
                    long loc = stream.Position;
                    stream.DiscardBytes(8);
                    uint[] ptrs = new uint[4];
                    ptrs[0] = stream.ReadUInt32().SwapEndian();
                    ptrs[1] = stream.ReadUInt32().SwapEndian();
                    ptrs[2] = stream.ReadUInt32().SwapEndian();
                    ptrs[3] = stream.ReadUInt32().SwapEndian();

                    if (stream.Position > textStart)
                    {
                        break;
                    }
                    if (ptrs.Any(x => x == 0))
                    {
                        break;
                    }
                    if (ptrs.Any(x => x + textPointerDiff < textStart))
                    {
                        break;
                    }
                    if (ptrs.Any(x => x + textPointerDiff >= filesize))
                    {
                        break;
                    }

                    var s = new ScenarioFileEntry();
                    s.Pointer       = (uint)loc;
                    stream.Position = ptrs[0] + textPointerDiff;
                    s.JpName        = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[1] + textPointerDiff;
                    s.JpText        = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[2] + textPointerDiff;
                    s.EnName        = stream.ReadShiftJisNullterm();
                    stream.Position = ptrs[3] + textPointerDiff;
                    s.EnText        = stream.ReadShiftJisNullterm();
                    EntryList.Add(s);

                    stream.Position = loc + 0x18;
                }
            }

            return(true);
        }
        /// <summary>
        ///     decompress an entire ME1 or 2 pcc file.
        /// </summary>
        /// <param name="raw">pcc file passed in stream format</param>
        /// <returns>a decompressed stream.</returns>
        public static MemoryStream DecompressME1orME2(Stream raw)
        {
            raw.Seek(4, SeekOrigin.Begin);
            ushort versionLo = raw.ReadUInt16();
            ushort versionHi = raw.ReadUInt16();

            raw.Seek(12, SeekOrigin.Begin);
            int tempNameSize = raw.ReadInt32();

            raw.Seek(64 + tempNameSize, SeekOrigin.Begin);
            int tempGenerations = raw.ReadInt32();

            raw.Seek(32 + tempGenerations * 12, SeekOrigin.Current);

            //if ME1
            if (versionLo == 491 && versionHi == 1008)
            {
                raw.Seek(4, SeekOrigin.Current);
            }

            CompressionType compressionType = (CompressionType)raw.ReadUInt32();


            int pos       = 4;
            int NumChunks = raw.ReadInt32();
            var Chunks    = new List <Chunk>();

            //DebugOutput.PrintLn("Reading chunk headers...");
            for (int i = 0; i < NumChunks; i++)
            {
                Chunk c = new Chunk
                {
                    uncompressedOffset = raw.ReadInt32(),
                    uncompressedSize   = raw.ReadInt32(),
                    compressedOffset   = raw.ReadInt32(),
                    compressedSize     = raw.ReadInt32()
                };
                c.Compressed   = new byte[c.compressedSize];
                c.Uncompressed = new byte[c.uncompressedSize];
                //DebugOutput.PrintLn("Chunk " + i + ", compressed size = " + c.compressedSize + ", uncompressed size = " + c.uncompressedSize);
                //DebugOutput.PrintLn("Compressed offset = " + c.compressedOffset + ", uncompressed offset = " + c.uncompressedOffset);
                Chunks.Add(c);
            }

            //DebugOutput.PrintLn("\tRead Chunks...");
            int count = 0;

            for (int i = 0; i < Chunks.Count; i++)
            {
                Chunk c = Chunks[i];
                raw.Seek(c.compressedOffset, SeekOrigin.Begin);
                c.Compressed = raw.ReadToBuffer(c.compressedSize);

                ChunkHeader h = new ChunkHeader
                {
                    magic            = BitConverter.ToInt32(c.Compressed, 0),
                    blocksize        = BitConverter.ToInt32(c.Compressed, 4),
                    compressedsize   = BitConverter.ToInt32(c.Compressed, 8),
                    uncompressedsize = BitConverter.ToInt32(c.Compressed, 12)
                };
                if (h.magic != -1641380927)
                {
                    throw new FormatException("Chunk magic number incorrect");
                }
                //DebugOutput.PrintLn("Chunkheader read: Magic = " + h.magic + ", Blocksize = " + h.blocksize + ", Compressed Size = " + h.compressedsize + ", Uncompressed size = " + h.uncompressedsize);
                pos = 16;
                int blockCount = (h.uncompressedsize % h.blocksize == 0)
                    ? h.uncompressedsize / h.blocksize
                    : h.uncompressedsize / h.blocksize + 1;
                var BlockList = new List <Block>();
                //DebugOutput.PrintLn("\t\t" + count + " Read Blockheaders...");
                for (int j = 0; j < blockCount; j++)
                {
                    Block b = new Block
                    {
                        compressedsize   = BitConverter.ToInt32(c.Compressed, pos),
                        uncompressedsize = BitConverter.ToInt32(c.Compressed, pos + 4)
                    };
                    //DebugOutput.PrintLn("Block " + j + ", compressed size = " + b.compressedsize + ", uncompressed size = " + b.uncompressedsize);
                    pos += 8;
                    BlockList.Add(b);
                }

                int outpos = 0;
                //DebugOutput.PrintLn("\t\t" + count + " Read and decompress Blocks...");
                foreach (Block b in BlockList)
                {
                    var datain  = new byte[b.compressedsize];
                    var dataout = new byte[b.uncompressedsize];
                    for (int j = 0; j < b.compressedsize; j++)
                    {
                        datain[j] = c.Compressed[pos + j];
                    }
                    pos += b.compressedsize;

                    switch (compressionType)
                    {
                    case CompressionType.LZO:
                    {
                        if (
                            LZO2.Decompress(datain, (uint)datain.Length, dataout) != b.uncompressedsize)
                        {
                            throw new Exception("LZO decompression failed!");
                        }
                        break;
                    }

                    case CompressionType.Zlib:
                    {
                        if (ZlibHelper.Zlib.Decompress(datain, (uint)datain.Length, dataout) != b.uncompressedsize)
                        {
                            throw new Exception("Zlib decompression failed!");
                        }
                        break;
                    }

                    default:
                        throw new Exception("Unknown compression type for this package.");
                    }

                    for (int j = 0; j < b.uncompressedsize; j++)
                    {
                        c.Uncompressed[outpos + j] = dataout[j];
                    }
                    outpos += b.uncompressedsize;
                }

                c.header = h;
                c.blocks = BlockList;
                count++;
                Chunks[i] = c;
            }

            MemoryStream result = new MemoryStream();

            foreach (Chunk c in Chunks)
            {
                result.Seek(c.uncompressedOffset, SeekOrigin.Begin);
                result.Write(c.Uncompressed);
            }

            return(result);
        }
        public static ShaderInfo DisassembleShader(Stream inStream, TextWriter writer = null)
        {
            uint vers       = inStream.ReadUInt32();
            var  minor      = vers.bits(7, 0);
            var  major      = vers.bits(15, 8);
            var  shaderType = (Frequency)vers.bits(31, 16);

            if (shaderType != Frequency.Pixel && shaderType != Frequency.Vertex)
            {
                Console.WriteLine("Not a valid Shader!");
                return(null);
            }

            int instructionCount    = 0;
            int texInstructionCount = 0;
            int indent     = 1;
            var shaderInfo = new ShaderInfo
            {
                Frequency = shaderType
            };

            while (inStream.Position + 4 <= inStream.Length)
            {
                uint token  = inStream.ReadUInt32();
                var  opcode = (OpcodeType)token.bits(15, 0);
                if (opcode == OpcodeType.D3DSIO_END)
                {
                    writer?.WriteLine();
                    writer?.WriteLine(shaderType == Frequency.Pixel
                                          ? $"// approximately {instructionCount + texInstructionCount} instruction slots used ({texInstructionCount} texture, {instructionCount} arithmetic)"
                                          : $"// approximately {instructionCount} instruction slots used");
                    return(shaderInfo);
                }
                else if (opcode == OpcodeType.D3DSIO_COMMENT)
                {
                    //writer?.WriteLine("Begin COMMENT");
                    uint length     = token.bits(30, 16);
                    long commentEnd = length * 4 + inStream.Position;
                    if (inStream.ReadUInt32() == CTAB)
                    {
                        long ctabPos = inStream.Position;
                        var  header  = new D3DConstantTable(inStream);
                        inStream.Seek(ctabPos + header.ConstantInfo, SeekOrigin.Begin);
                        var constantInfos = new ConstRegisterInfo[header.Constants];
                        for (int i = 0; i < header.Constants; i++)
                        {
                            constantInfos[i] = new ConstRegisterInfo(inStream);
                        }

                        inStream.Seek(ctabPos + header.Creator, SeekOrigin.Begin);
                        string creator = inStream.ReadString();
                        writer?.WriteLine("//");
                        writer?.WriteLine($"// Generated by {creator}");
                        writer?.WriteLine("//");
                        shaderInfo.Constants = new ConstantInfo[header.Constants];
                        //writer?.WriteLine("BEGIN Constant Table");
                        for (int i = 0; i < constantInfos.Length; i++)
                        {
                            ConstRegisterInfo info = constantInfos[i];
                            inStream.Seek(ctabPos + info.TypeInfo, SeekOrigin.Begin);
                            var type = new TypeInfo(inStream);
                            inStream.Seek(ctabPos + info.Name, SeekOrigin.Begin);
                            string name = inStream.ReadString();
                            shaderInfo.Constants[i] = new ConstantInfo(name,
                                                                       (D3DXREGISTER_SET)info.RegisterSet,
                                                                       info.RegisterIndex,
                                                                       info.RegisterCount,
                                                                       info.DefaultValue,
                                                                       (D3DXPARAMETER_CLASS)type.Class,
                                                                       (D3DXPARAMETER_TYPE)type.Type,
                                                                       type.Rows,
                                                                       type.Columns,
                                                                       type.Elements,
                                                                       new StructMember[0]);
#if DEBUGGING
                            writer?.WriteLine();
                            writer?.WriteLine(name);
                            writer?.WriteLine($"RegisterSet: {(D3DXREGISTER_SET)info.RegisterSet}, RegisterIndex: {info.RegisterIndex}, RegisterCount: {info.RegisterCount}," +
                                              $" DefaultValue: {info.DefaultValue}");
                            writer?.WriteLine($"Class: {(D3DXPARAMETER_CLASS)type.Class}, Type: {(D3DXPARAMETER_TYPE)type.Type}, Rows: {type.Rows}, Columns: {type.Columns}," +
                                              $" Elements: {type.Elements}, StructMembers {type.StructMembers}, StructMemberInfo: {type.StructMemberInfo}");
#endif
                        }

                        writer?.WriteLine("// Parameters:");
                        writer?.WriteLine("//");
                        foreach (ConstantInfo info in shaderInfo.Constants)
                        {
                            string line = $"//   {d3d9types.paramTypes[info.ParameterType]}";
                            switch (info.ParameterClass)
                            {
                            case D3DXPARAMETER_CLASS.SCALAR:
                            case D3DXPARAMETER_CLASS.OBJECT:
                                break;

                            case D3DXPARAMETER_CLASS.VECTOR:
                                line += info.Columns;
                                break;

                            case D3DXPARAMETER_CLASS.MATRIX_COLUMNS:
                                line += $"{info.Rows}x{info.Columns}";
                                break;

                            case D3DXPARAMETER_CLASS.MATRIX_ROWS:
                                line += "ROWS?????????";
                                break;

                            case D3DXPARAMETER_CLASS.STRUCT:
                                line += "STRUCT?????????";
                                break;
                            }

                            line += " ";
                            line += info.Name;
                            if (info.Elements > 1)
                            {
                                line += $"[{info.Elements}]";
                            }

                            line += ";";
                            writer?.WriteLine(line);
                        }

                        writer?.WriteLine("//");
                        writer?.WriteLine("//");

                        int maxNameLength  = Math.Max(12, shaderInfo.Constants.Max(c => c.Name.Length));
                        int regTextLength  = Math.Max(5, shaderInfo.Constants.Max(c => c.RegisterIndex.NumDigits()) + 1);
                        int sizeTextLength = Math.Max(4, shaderInfo.Constants.Max(c => c.RegisterCount.NumDigits()));
                        writer?.WriteLine("// Registers:");
                        writer?.WriteLine("//");
                        writer?.WriteLine($"//   {"Name".PadRight(maxNameLength)} {"Reg".PadRight(regTextLength)} {"Size".PadRight(sizeTextLength)}");
                        writer?.WriteLine($"//   {new string('-', maxNameLength)} {new string('-', regTextLength)} {new string('-', sizeTextLength)}");
                        foreach (ConstantInfo info in shaderInfo.Constants.OrderBy(c => c.RegisterSet).ThenBy(c => c.RegisterIndex))
                        {
                            writer?.WriteLine($"//   {info.Name.PadRight(maxNameLength)} {d3d9types.registerSets[info.RegisterSet]}{info.RegisterIndex.ToString().PadRight(regTextLength - 1)}" +
                                              $" {info.RegisterCount.ToString().PadLeft(sizeTextLength)}");
                        }

                        writer?.WriteLine("//");

                        //writer?.WriteLine("END Constant Table");
                    }

                    inStream.Seek(commentEnd, SeekOrigin.Begin);
                    //writer?.WriteLine("End COMMENT");
                    writer?.WriteLine();
                    writer?.WriteLine($"    {(shaderType == Frequency.Pixel ? "ps" : "vs")}_{major}_{minor}");
                }
                else if (opcode == OpcodeType.D3DSIO_DCL)
                {
                    uint   declToken       = inStream.ReadUInt32();
                    var    declarationType = (D3DDECLUSAGE)declToken.bits(4, 0);
                    var    samplerTexType  = (D3DSAMPLER_TEXTURE_TYPE)declToken.bits(30, 27);
                    string suffix          = "";
                    if (samplerTexType != D3DSAMPLER_TEXTURE_TYPE.D3DSTT_UNKNOWN)
                    {
                        suffix = d3d9types.samplerTexTypes[samplerTexType];
                    }
                    else
                    {
                        suffix = d3d9types.declarationTypes[declarationType];
                        uint usageIndex = declToken.bits(19, 16);
                        if (usageIndex != 0)
                        {
                            suffix += usageIndex;
                        }

                        uint destToken = inStream.ReadUInt32();
                        inStream.Seek(-4, SeekOrigin.Current);
                        var declaration = new ParameterDeclaration(declarationType,
                                                                   (int)usageIndex,
                                                                   (D3DSHADER_PARAM_REGISTER_TYPE)(destToken.bits(30, 28) | (destToken.bits(12, 11) << 3)),
                                                                   (int)destToken.bits(10, 0),
                                                                   new WriteMask(destToken.bit(16), destToken.bit(17), destToken.bit(18), destToken.bit(19)),
                                                                   ((ResultModifiers)token.bits(23, 20)).HasFlag(ResultModifiers.Partial_Precision));
                        if (declaration.RegisterType == D3DSHADER_PARAM_REGISTER_TYPE.INPUT)
                        {
                            shaderInfo.InputDeclarations.Add(declaration);
                        }
                        else
                        {
                            shaderInfo.OutputDeclarations.Add(declaration);
                        }
                    }


                    string destinationParameterTokenString = ReadDestinationParameterToken(inStream, shaderType);
                    writer?.WriteLine($"    dcl{suffix}{destinationParameterTokenString}");
                }
                else
                {
                    instructionCount++;
                    uint instructionSize = token.bits(27, 24);
                    bool isPredicated    = token.bit(28); //todo: implement
                    //writer?.WriteLine($"{d3d9types.opcodeNames[opcode]} (instruction size: {instructionSize})");
                    var    parameters = new List <string>();
                    string line;
                    void setLineStart() => line = $"{new string(' ', indent * 4)}{d3d9types.opcodeNames[opcode]}";

                    string appendComparison()
                    {
                        //todo: not sure about this, test
                        switch (token.bits(23, 16))
                        {
                        case 0:
                            line += "_gt";
                            break;

                        case 1:
                            line += "_lt";
                            break;

                        case 2:
                            line += "_ge";
                            break;

                        case 3:
                            line += "_le";
                            break;

                        case 4:
                            line += "_eq";
                            break;

                        case 5:
                            line += "_ne";
                            break;
                        }

                        return(line);
                    }

                    setLineStart();

                    switch (opcode)
                    {
                    case OpcodeType.D3DSIO_NOP:
                    case OpcodeType.D3DSIO_RET:
                    case OpcodeType.D3DSIO_BREAK:
                        break;

                    case OpcodeType.D3DSIO_MOV:
                    case OpcodeType.D3DSIO_RCP:
                    case OpcodeType.D3DSIO_RSQ:
                    case OpcodeType.D3DSIO_EXP:
                    case OpcodeType.D3DSIO_LOG:
                    case OpcodeType.D3DSIO_LIT:
                    case OpcodeType.D3DSIO_FRC:
                    case OpcodeType.D3DSIO_ABS:
                    case OpcodeType.D3DSIO_NRM:
                    case OpcodeType.D3DSIO_MOVA:
                    case OpcodeType.D3DSIO_EXPP:
                    case OpcodeType.D3DSIO_DSX:
                    case OpcodeType.D3DSIO_DSY:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_ADD:
                    case OpcodeType.D3DSIO_SUB:
                    case OpcodeType.D3DSIO_MUL:
                    case OpcodeType.D3DSIO_DP3:
                    case OpcodeType.D3DSIO_DP4:
                    case OpcodeType.D3DSIO_MIN:
                    case OpcodeType.D3DSIO_MAX:
                    case OpcodeType.D3DSIO_SLT:
                    case OpcodeType.D3DSIO_SGE:
                    case OpcodeType.D3DSIO_DST:
                    case OpcodeType.D3DSIO_M4x4:
                    case OpcodeType.D3DSIO_M4x3:
                    case OpcodeType.D3DSIO_M3x4:
                    case OpcodeType.D3DSIO_M3x3:
                    case OpcodeType.D3DSIO_M3x2:
                    case OpcodeType.D3DSIO_POW:
                    case OpcodeType.D3DSIO_CRS:
                    case OpcodeType.D3DSIO_LOGP:
                    case OpcodeType.D3DSIO_BEM:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_MAD:
                    case OpcodeType.D3DSIO_LRP:
                    case OpcodeType.D3DSIO_SGN:
                    case OpcodeType.D3DSIO_CND:
                    case OpcodeType.D3DSIO_CMP:
                    case OpcodeType.D3DSIO_DP2ADD:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_CALL:
                        parameters.Add(ReadLabelToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_CALLNZ:
                        parameters.Add(ReadLabelToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_LOOP:
                        parameters.Add("aL");
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        indent++;
                        break;

                    case OpcodeType.D3DSIO_REP:
                    case OpcodeType.D3DSIO_IF:
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        indent++;
                        break;

                    case OpcodeType.D3DSIO_IFC:
                        line = appendComparison();
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        indent++;
                        break;

                    case OpcodeType.D3DSIO_ELSE:
                        indent--;
                        setLineStart();
                        indent++;
                        break;

                    case OpcodeType.D3DSIO_ENDREP:
                    case OpcodeType.D3DSIO_ENDLOOP:
                    case OpcodeType.D3DSIO_ENDIF:
                        indent--;
                        //these shouldn't be indented, so rewrite the opcode
                        setLineStart();
                        break;

                    case OpcodeType.D3DSIO_LABEL:
                    case OpcodeType.D3DSIO_BREAKP:
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_SINCOS:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        //unclear to me whether this has 2 or 4 parameters
                        if (instructionSize == 4)
                        {
                            parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                            parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        }

                        break;

                    case OpcodeType.D3DSIO_BREAKC:
                        line = appendComparison();
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_SETP:
                        line = appendComparison();
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_DEF:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add($"{inStream.ReadFloat()}");
                        parameters.Add($"{inStream.ReadFloat()}");
                        parameters.Add($"{inStream.ReadFloat()}");
                        parameters.Add($"{inStream.ReadFloat()}");
                        instructionCount--;
                        break;

                    case OpcodeType.D3DSIO_DEFB:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add($"{inStream.ReadUInt32() > 0}");
                        instructionCount--;
                        break;

                    case OpcodeType.D3DSIO_DEFI:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add($"{inStream.ReadInt32()}");
                        parameters.Add($"{inStream.ReadInt32()}");
                        parameters.Add($"{inStream.ReadInt32()}");
                        parameters.Add($"{inStream.ReadInt32()}");
                        instructionCount--;
                        break;

                    case OpcodeType.D3DSIO_TEXKILL:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        break;

                    case OpcodeType.D3DSIO_TEXLDD:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        texInstructionCount++;
                        break;

                    case OpcodeType.D3DSIO_TEX:
                    case OpcodeType.D3DSIO_TEXM3x3SPEC:
                    case OpcodeType.D3DSIO_TEXLDL:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        texInstructionCount++;
                        break;

                    case OpcodeType.D3DSIO_TEXBEM:
                    case OpcodeType.D3DSIO_TEXBEML:
                    case OpcodeType.D3DSIO_TEXREG2AR:
                    case OpcodeType.D3DSIO_TEXREG2GB:
                    case OpcodeType.D3DSIO_TEXM3x2PAD:
                    case OpcodeType.D3DSIO_TEXM3x2TEX:
                    case OpcodeType.D3DSIO_TEXM3x3PAD:
                    case OpcodeType.D3DSIO_TEXM3x3TEX:
                    case OpcodeType.D3DSIO_TEXM3x3VSPEC:
                    case OpcodeType.D3DSIO_TEXREG2RGB:
                    case OpcodeType.D3DSIO_TEXDP3TEX:
                    case OpcodeType.D3DSIO_TEXM3x2DEPTH:
                    case OpcodeType.D3DSIO_TEXDP3:
                    case OpcodeType.D3DSIO_TEXM3x3:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        parameters.Add(ReadSourceParameterToken(inStream, shaderType));
                        texInstructionCount++;
                        break;

                    case OpcodeType.D3DSIO_TEXDEPTH:
                        parameters.Add(ReadDestinationParameterToken(inStream, shaderType));
                        texInstructionCount++;
                        break;

                    default:
                        for (; instructionSize > 0; instructionSize--)
                        {
                            inStream.ReadUInt32();
                        }

                        break;
                    }

                    writer?.WriteLine($"{line}{string.Join(", ", parameters)}");
                }
            }

            Console.WriteLine("No End Token found!");
            return(null);
        }
Exemplo n.º 54
0
 public uint GetCodeHandlerAddress()
 {
     Stream.WriteCommand(GckCommands.GetCodeHandlerAddress);
     Stream.Flush();
     return(Stream.ReadUInt32());
 }
 //https://docs.microsoft.com/en-us/windows-hardware/drivers/display/label-token
 private static string ReadLabelToken(Stream fs, Frequency shaderType)
 {
     return(" " + getRegister(fs.ReadUInt32(), shaderType));
 }
        /// <summary>
        ///     decompress an entire ME3 pcc file into a new stream
        /// </summary>
        /// <param name="input">pcc file passed in stream format</param>
        /// <returns>a decompressed array of bytes</returns>
        public static MemoryStream DecompressME3(Stream input)
        {
            input.Seek(0, SeekOrigin.Begin);
            var magic = input.ReadUInt32();

            if (magic != 0x9E2A83C1)
            {
                throw new FormatException("not a pcc file");
            }


            var versionLo = input.ReadUInt16();
            var versionHi = input.ReadUInt16();

            if (versionLo != 684 &&
                versionHi != 194)
            {
                throw new FormatException("unsupported pcc version");
            }

            long headerSize = 8;

            input.Seek(4, SeekOrigin.Current);
            headerSize += 4;

            var folderNameLength = input.ReadInt32();

            headerSize += 4;

            var folderNameByteLength =
                folderNameLength >= 0 ? folderNameLength : (-folderNameLength * 2);

            input.Seek(folderNameByteLength, SeekOrigin.Current);
            headerSize += folderNameByteLength;

            var packageFlagsOffset = input.Position;
            var packageFlags       = input.ReadUInt32();

            headerSize += 4;

            if ((packageFlags & 0x02000000u) == 0)
            {
                throw new FormatException("pcc file is already decompressed");
            }

            if ((packageFlags & 8) != 0)
            {
                input.Seek(4, SeekOrigin.Current);
                headerSize += 4;
            }

            uint nameCount  = input.ReadUInt32();
            uint nameOffset = input.ReadUInt32();

            input.Seek(52, SeekOrigin.Current);
            headerSize += 60;

            var generationsCount = input.ReadUInt32();

            input.Seek(generationsCount * 12, SeekOrigin.Current);
            headerSize += generationsCount * 12;

            input.Seek(20, SeekOrigin.Current);
            headerSize += 24;

            var blockCount            = input.ReadUInt32();
            int headBlockOff          = (int)input.Position;
            var afterBlockTableOffset = headBlockOff + (blockCount * 16);
            var indataOffset          = afterBlockTableOffset + 8;

            input.Seek(0, SeekOrigin.Begin);
            MemoryStream output = new MemoryStream();

            output.Seek(0, SeekOrigin.Begin);

            output.WriteFromStream(input, headerSize);
            output.WriteUInt32(0); // block count

            input.Seek(afterBlockTableOffset, SeekOrigin.Begin);
            output.WriteFromStream(input, 8);

            //check if has extra name list (don't know it's usage...)
            if ((packageFlags & 0x10000000) != 0)
            {
                long curPos = output.Position;
                output.WriteFromStream(input, nameOffset - curPos);
            }

            //decompress blocks in parallel
            var tasks = new Task <byte[]> [blockCount];
            var uncompressedOffsets = new uint[blockCount];

            for (int i = 0; i < blockCount; i++)
            {
                input.Seek(headBlockOff, SeekOrigin.Begin);
                uncompressedOffsets[i] = input.ReadUInt32();
                var uncompressedSize = input.ReadUInt32();
                var compressedOffset = input.ReadUInt32();
                var compressedSize   = input.ReadUInt32();
                headBlockOff = (int)input.Position;

                var buff = new byte[compressedSize];
                input.Seek(compressedOffset, SeekOrigin.Begin);
                input.Read(buff, 0, buff.Length);

                tasks[i] = AmaroK86.MassEffect3.ZlibBlock.ZBlock.DecompressAsync(buff);
            }

            Task.WaitAll(tasks);
            for (int i = 0; i < blockCount; i++)
            {
                output.Seek(uncompressedOffsets[i], SeekOrigin.Begin);
                output.Write(tasks[i].Result);
            }

            //Do not change the IsCompressed bit as it will not accurately reflect the state of the file on disk.
            //output.Seek(packageFlagsOffset, SeekOrigin.Begin);
            //output.WriteValueU32(packageFlags & ~0x02000000u, endian); //Mark file as decompressed.
            return(output);
        }
Exemplo n.º 57
0
        // VQA Frame
        public void DecodeVQFR(Stream s)
        {
            while (true)
            {
                // Chunks are aligned on even bytes; may be padded with a single null
                if (s.Peek() == 0)
                {
                    s.ReadByte();
                }
                var type           = s.ReadASCII(4);
                int subchunkLength = (int)int2.Swap(s.ReadUInt32());

                switch (type)
                {
                // Full frame-modifier
                case "CBFZ":
                    Format80.DecodeInto(s.ReadBytes(subchunkLength), cbf);
                    break;

                case "CBF0":
                    cbf = s.ReadBytes(subchunkLength);
                    break;

                // frame-modifier chunk
                case "CBP0":
                case "CBPZ":
                    // Partial buffer is full; dump and recreate
                    if (cbChunk == cbParts)
                    {
                        if (type == "CBP0")
                        {
                            cbf = (byte[])cbp.Clone();
                        }
                        else
                        {
                            Format80.DecodeInto(cbp, cbf);
                        }

                        cbOffset = cbChunk = 0;
                    }

                    var bytes = s.ReadBytes(subchunkLength);
                    bytes.CopyTo(cbp, cbOffset);
                    cbOffset += subchunkLength;
                    cbChunk++;
                    break;

                // Palette
                case "CPL0":
                    for (int i = 0; i < numColors; i++)
                    {
                        byte r = (byte)(s.ReadUInt8() << 2);
                        byte g = (byte)(s.ReadUInt8() << 2);
                        byte b = (byte)(s.ReadUInt8() << 2);
                        palette[i] = (uint)((255 << 24) | (r << 16) | (g << 8) | b);
                    }
                    break;

                // Frame data
                case "VPTZ":
                    Format80.DecodeInto(s.ReadBytes(subchunkLength), origData);
                    // This is the last subchunk
                    return;

                default:
                    throw new InvalidDataException("Unknown sub-chunk {0}".F(type));
                }
            }
        }
Exemplo n.º 58
0
        private bool LoadFile(Stream stream, Util.Endianness endian, Util.Bitness bits)
        {
            string magic                    = stream.ReadAscii(8);
            uint   fileSize                 = stream.ReadUInt32().FromEndian(endian);
            uint   skitInfoCount            = stream.ReadUInt32().FromEndian(endian);
            uint   skitInfoOffset           = stream.ReadUInt32().FromEndian(endian);
            uint   conditionForwarderCount  = stream.ReadUInt32().FromEndian(endian);
            uint   conditionForwarderOffset = stream.ReadUInt32().FromEndian(endian);
            uint   conditionCount           = stream.ReadUInt32().FromEndian(endian);
            uint   conditionOffset          = stream.ReadUInt32().FromEndian(endian);
            uint   uCount4                  = stream.ReadUInt32().FromEndian(endian);
            uint   uOffset4                 = stream.ReadUInt32().FromEndian(endian);
            uint   uCount5                  = stream.ReadUInt32().FromEndian(endian);
            uint   uOffset5                 = stream.ReadUInt32().FromEndian(endian);
            uint   refStringStart           = stream.ReadUInt32().FromEndian(endian);

            SkitInfoList    = new List <SkitInfo>((int)skitInfoCount);
            stream.Position = skitInfoOffset;
            for (uint i = 0; i < skitInfoCount; ++i)
            {
                SkitInfo s = new SkitInfo(stream, refStringStart, endian, bits);
                SkitInfoList.Add(s);
            }

            SkitConditionForwarderList = new List <SkitConditionForwarder>((int)conditionForwarderCount);
            stream.Position            = conditionForwarderOffset;
            for (uint i = 0; i < conditionForwarderCount; ++i)
            {
                var s = new SkitConditionForwarder(stream, endian, bits);
                SkitConditionForwarderList.Add(s);
            }

            SkitConditionList = new List <SkitCondition>((int)conditionCount);
            stream.Position   = conditionOffset;
            for (uint i = 0; i < conditionCount; ++i)
            {
                var s = new SkitCondition(stream, endian);
                SkitConditionList.Add(s);
            }

            UnknownSkitData4List = new List <UnknownSkitData4>((int)uCount4);
            stream.Position      = uOffset4;
            for (uint i = 0; i < uCount4; ++i)
            {
                var s = new UnknownSkitData4(stream, endian, bits);
                UnknownSkitData4List.Add(s);
            }

            UnknownSkitData5List = new List <UnknownSkitData5>((int)uCount5);
            stream.Position      = uOffset5;
            for (uint i = 0; i < uCount5; ++i)
            {
                var s = new UnknownSkitData5(stream, endian, bits);
                UnknownSkitData5List.Add(s);
            }

            return(true);
        }
Exemplo n.º 59
0
        public static WAV.Header ReadWAVHeader(this Stream IO)
        {
            WAV.Header Header = new WAV.Header();
            if (IO.ReadString(4) != "RIFF")
            {
                return(Header);
            }
            IO.ReadUInt32();
            if (IO.ReadString(4) != "WAVE")
            {
                return(Header);
            }
            if (IO.ReadString(4) != "fmt ")
            {
                return(Header);
            }
            int Offset = IO.ReadInt32();

            Header.Format = IO.ReadUInt16();
            if (Header.Format == 0x01 || Header.Format == 0x03 || Header.Format == 0xFFFE)
            {
                Header.Channels   = IO.ReadUInt16();
                Header.SampleRate = IO.ReadUInt32();
                IO.ReadInt32(); IO.ReadInt16();
                Header.Bytes = IO.ReadUInt16();
                if (Header.Bytes % 8 != 0)
                {
                    return(Header);
                }
                Header.Bytes >>= 3;
                if (Header.Bytes == 0)
                {
                    return(Header);
                }
                if (Header.Format == 0xFFFE)
                {
                    IO.ReadInt32();
                    Header.ChannelMask = IO.ReadUInt32();
                    Header.Format      = IO.ReadUInt16();
                }
                if (Header.Bytes < 1 || (Header.Bytes > 4 && Header.Bytes != 8))
                {
                    return(Header);
                }
                if (Header.Bytes > 0 && Header.Bytes < 4 && Header.Format == 3)
                {
                    return(Header);
                }
                if (Header.Bytes == 8 && Header.Format == 1)
                {
                    return(Header);
                }
                IO.Seek(Offset + 0x14, 0);
                if (IO.ReadString(4) != "data")
                {
                    return(Header);
                }
                Header.Size        = IO.ReadUInt32();
                Header.HeaderSize  = IO.UIntPosition;
                Header.IsSupported = true;
                return(Header);
            }
            return(Header);
        }
Exemplo n.º 60
0
        public VqaReader(Stream stream)
        {
            this.stream = stream;

            // Decode FORM chunk
            if (stream.ReadASCII(4) != "FORM")
            {
                throw new InvalidDataException("Invalid vqa (invalid FORM section)");
            }
            /*var length = */ stream.ReadUInt32();

            if (stream.ReadASCII(8) != "WVQAVQHD")
            {
                throw new InvalidDataException("Invalid vqa (not WVQAVQHD)");
            }
            /* var length = */ stream.ReadUInt32();

            /*var version = */ stream.ReadUInt16();
            /*var flags = */ stream.ReadUInt16();
            Frames = stream.ReadUInt16();
            Width  = stream.ReadUInt16();
            Height = stream.ReadUInt16();

            blockWidth  = stream.ReadUInt8();
            blockHeight = stream.ReadUInt8();
            Framerate   = stream.ReadUInt8();
            cbParts     = stream.ReadUInt8();
            blocks      = new int2(Width / blockWidth, Height / blockHeight);

            numColors = stream.ReadUInt16();
            /*var maxBlocks = */ stream.ReadUInt16();
            /*var unknown1 = */ stream.ReadUInt16();
            /*var unknown2 = */ stream.ReadUInt32();

            // Audio
            /*var freq = */ stream.ReadUInt16();
            /*var channels = */ stream.ReadByte();
            /*var bits = */ stream.ReadByte();
            /*var unknown3 = */ stream.ReadBytes(14);

            var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));

            cbf       = new byte[Width * Height];
            cbp       = new byte[Width * Height];
            palette   = new uint[numColors];
            origData  = new byte[2 * blocks.X * blocks.Y];
            frameData = new uint[frameSize, frameSize];

            var type = stream.ReadASCII(4);

            if (type != "FINF")
            {
                stream.Seek(27, SeekOrigin.Current);
                type = stream.ReadASCII(4);
            }

            /*var length = */ stream.ReadUInt16();
            /*var unknown4 = */ stream.ReadUInt16();

            // Frame offsets
            offsets = new UInt32[Frames];
            for (int i = 0; i < Frames; i++)
            {
                offsets[i] = stream.ReadUInt32();
                if (offsets[i] > 0x40000000)
                {
                    offsets[i] -= 0x40000000;
                }
                offsets[i] <<= 1;
            }

            CollectAudioData();

            Reset();
        }