private void ParseHeader() { string archivePath = Path.Combine(directoryLocation, GetArchiveName(DIR_PAK) + ".vpk"); if (File.Exists(archivePath)) { header = new VPKHeader(); preloadStream = new FileStream(archivePath, FileMode.Open, FileAccess.Read); uint signature = DataParser.ReadUInt(preloadStream); if (signature != VPKHeader.Signature) { return; } header.Version = DataParser.ReadUInt(preloadStream); header.TreeSize = DataParser.ReadUInt(preloadStream); headerSize = 12; if (header.Version > 1) { header.FileDataSectionSize = DataParser.ReadUInt(preloadStream); header.ArchiveMD5SectionSize = DataParser.ReadUInt(preloadStream); header.OtherMD5SectionSize = DataParser.ReadUInt(preloadStream); header.SignatureSectionSize = DataParser.ReadUInt(preloadStream); headerSize += 16; } ParseTree(preloadStream); } }
private void ParseTree(Stream currentStream) { while (currentStream.Position < header.TreeSize) { string extension = DataParser.ReadNullTerminatedString(currentStream).ToLower(); if (extension.Length <= 0) { extension = tree.Keys.ElementAt(tree.Count - 1); } else { if (!tree.ContainsKey(extension)) { tree.Add(extension, new Dictionary <string, Dictionary <string, VPKDirectoryEntry> >()); } } while (true) { string directory = DataParser.ReadNullTerminatedString(currentStream).ToLower(); if (directory.Length <= 0) { break; } if (!tree[extension].ContainsKey(directory)) { tree[extension].Add(directory, new Dictionary <string, VPKDirectoryEntry>()); } string fileName; do { fileName = DataParser.ReadNullTerminatedString(currentStream).ToLower(); if (!string.IsNullOrEmpty(fileName)) { VPKDirectoryEntry dirEntry = new VPKDirectoryEntry(); dirEntry.CRC = DataParser.ReadUInt(currentStream); dirEntry.PreloadBytes = DataParser.ReadUShort(currentStream); dirEntry.ArchiveIndex = DataParser.ReadUShort(currentStream); dirEntry.EntryOffset = DataParser.ReadUInt(currentStream); dirEntry.EntryLength = DataParser.ReadUInt(currentStream); ushort terminator = DataParser.ReadUShort(currentStream); if (dirEntry.EntryOffset == 0 && dirEntry.ArchiveIndex == DIR_PAK) { dirEntry.EntryOffset = Convert.ToUInt32(currentStream.Position); } if (dirEntry.EntryLength == 0) { dirEntry.EntryLength = dirEntry.PreloadBytes; } currentStream.Position += dirEntry.PreloadBytes; if (!tree[extension][directory].ContainsKey(fileName)) { tree[extension][directory].Add(fileName, dirEntry); } } }while (!string.IsNullOrEmpty(fileName)); } } }
public static Color[] LoadVTFFile(Stream stream, long vtfBytePosition, out int width, out int height) { //Texture2D extracted = null; Color[] extracted = null; width = 0; height = 0; if (stream != null) { stream.Position = vtfBytePosition; int signature = DataParser.ReadInt(stream); if (signature == VTFHeader.signature) { #region Read Header VTFHeader vtfHeader; uint[] version = new uint[] { DataParser.ReadUInt(stream), DataParser.ReadUInt(stream) }; vtfHeader.version = (version[0]) + (version[1] / 10f); vtfHeader.headerSize = DataParser.ReadUInt(stream); vtfHeader.width = DataParser.ReadUShort(stream); vtfHeader.height = DataParser.ReadUShort(stream); vtfHeader.flags = DataParser.ReadUInt(stream); vtfHeader.frames = DataParser.ReadUShort(stream); vtfHeader.firstFrame = DataParser.ReadUShort(stream); vtfHeader.padding0 = new byte[4]; stream.Read(vtfHeader.padding0, 0, 4); vtfHeader.reflectivity = new float[] { DataParser.ReadFloat(stream), DataParser.ReadFloat(stream), DataParser.ReadFloat(stream) }; vtfHeader.padding1 = new byte[4]; stream.Read(vtfHeader.padding1, 0, 4); vtfHeader.bumpmapScale = DataParser.ReadFloat(stream); vtfHeader.highResImageFormat = (VTFImageFormat)DataParser.ReadUInt(stream); vtfHeader.mipmapCount = DataParser.ReadByte(stream); vtfHeader.lowResImageFormat = (VTFImageFormat)DataParser.ReadUInt(stream); vtfHeader.lowResImageWidth = DataParser.ReadByte(stream); vtfHeader.lowResImageHeight = DataParser.ReadByte(stream); vtfHeader.depth = 1; vtfHeader.resourceCount = 0; vtfHeader.resources = new VTFResource[0]; if (vtfHeader.version >= 7.2f) { vtfHeader.depth = DataParser.ReadUShort(stream); if (vtfHeader.version >= 7.3) { vtfHeader.padding2 = new byte[3]; stream.Read(vtfHeader.padding2, 0, 3); vtfHeader.resourceCount = DataParser.ReadUInt(stream); if (vtfHeader.version >= 7.4) { vtfHeader.padding3 = new byte[8]; stream.Read(vtfHeader.padding3, 0, 8); vtfHeader.resources = new VTFResource[vtfHeader.resourceCount]; for (int i = 0; i < vtfHeader.resources.Length; i++) { vtfHeader.resources[i].type = DataParser.ReadUInt(stream); vtfHeader.resources[i].data = DataParser.ReadUInt(stream); } } } } #endregion int thumbnailBufferSize = 0; int imageBufferSize = (int)ComputeImageBufferSize(vtfHeader.width, vtfHeader.height, vtfHeader.depth, vtfHeader.mipmapCount, vtfHeader.highResImageFormat) * vtfHeader.frames; if (vtfHeader.lowResImageFormat != VTFImageFormat.IMAGE_FORMAT_NONE) { thumbnailBufferSize = (int)ComputeImageBufferSize(vtfHeader.lowResImageWidth, vtfHeader.lowResImageHeight, 1, vtfHeader.lowResImageFormat); } int thumbnailBufferOffset = 0, imageBufferOffset = 0; #region Read Resource Directories if (vtfHeader.resources.Length > 0) { for (int i = 0; i < vtfHeader.resources.Length; i++) { if ((VTFResourceEntryType)vtfHeader.resources[i].type == VTFResourceEntryType.VTF_LEGACY_RSRC_LOW_RES_IMAGE) { thumbnailBufferOffset = (int)vtfHeader.resources[i].data; } if ((VTFResourceEntryType)vtfHeader.resources[i].type == VTFResourceEntryType.VTF_LEGACY_RSRC_IMAGE) { imageBufferOffset = (int)vtfHeader.resources[i].data; } } } else { thumbnailBufferOffset = (int)vtfHeader.headerSize; imageBufferOffset = thumbnailBufferOffset + thumbnailBufferSize; } #endregion if (vtfHeader.highResImageFormat != VTFImageFormat.IMAGE_FORMAT_NONE) { int mipmapBufferOffset = 0; for (uint i = 1; i <= vtfHeader.mipmapCount; i++) { mipmapBufferOffset += (int)ComputeMipmapSize(vtfHeader.width, vtfHeader.height, vtfHeader.depth, i, vtfHeader.highResImageFormat); } stream.Position = vtfBytePosition + imageBufferOffset + mipmapBufferOffset; extracted = DecompressImage(stream, vtfHeader.width, vtfHeader.height, vtfHeader.highResImageFormat); width = vtfHeader.width; height = vtfHeader.height; } else { Debug.LogError("SourceTexture: Image format given was none"); } } else { Debug.LogError("SourceTexture: Signature mismatch " + signature + " != " + VTFHeader.signature); } } else { Debug.LogError("SourceTexture: Missing VTF data"); } return(extracted); }