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; }
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; } }
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(); } }
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; } }
/// <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(); } }
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; } }
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()); } } }
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)); } }
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; }
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(); }
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; }
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); } } }
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; }
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; }
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; }
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; }
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; } }
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; }
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; }
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; }
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(); }
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; }
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; } } }
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); }
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); } }
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; }
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; }
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; }
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)); } }
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()); }
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; }
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(); }
// 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)); } } }
public PackageEntry(Stream s) { Hash = s.ReadUInt32(); Offset = s.ReadUInt32(); Length = s.ReadUInt32(); }
public static bool ReadValueB32(this Stream stream, Endian endian) { return(stream.ReadUInt32(endian) != 0); }
public static unsafe float ReadSingle(this Stream s) { var ret = s.ReadUInt32(); return(*((float *)&ret)); }
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); }
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(); } }
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); }
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]; } }
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"); } }
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; }
// 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)); } } }
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; }
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; }
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(); }
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); }
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); }
// 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)); } } }
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); }
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); }
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(); }