public static bool SplitPkf(Byte[] File, string Directory) { try { System.IO.Directory.CreateDirectory(Directory); uint location = 0; while (true) { byte Ident = File[location]; uint CompressedSize = BitConverter.ToUInt32(File, (int)location + 1); uint DecompressedSize = BitConverter.ToUInt32(File, (int)location + 5); byte[] SplitFile = new byte[CompressedSize + 9]; ArrayUtils.CopyByteArrayPart(File, (int)location, SplitFile, 0, (int)CompressedSize + 9); System.IO.File.WriteAllBytes(Directory + "/" + location.ToString("X8") + ".c", SplitFile); location = NumberUtils.Align(location + CompressedSize + 9, 0x800u); if (location >= File.Length) { break; } } } catch (Exception) { return(false); } return(true); }
public override Stream GetSinglePlane(Stream inputStream, uint depthlevel) { if (Mipmaps > 1) { throw new Exception("Don't know how to deal with volume textures with mipmaps."); } if (!(Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b)) { throw new Exception("Volume textures only implemented for DXT formats."); } // Format reference: https://www.khronos.org/registry/OpenGL/extensions/NV/NV_texture_compression_vtc.txt uint bytecount = GetByteCountSingleDepthPlane(0); uint group = depthlevel / 4u; uint texInGroupBefore = depthlevel % 4u; uint texInGroupAfter = 3u - texInGroupBefore; // special handling for last group if depth not divisible by 4 uint nonDivisiblePlanesAtEnd = Depth % 4; uint groupCount = NumberUtils.Align(Depth, 4u) / 4; if (nonDivisiblePlanesAtEnd != 0 && group == (groupCount - 1u)) { texInGroupAfter = (nonDivisiblePlanesAtEnd - texInGroupBefore) - 1u; } uint bytesPerTexLine; switch (Format) { case TextureFormat.DXT1a: case TextureFormat.DXT1b: bytesPerTexLine = 8; break; case TextureFormat.DXT5a: case TextureFormat.DXT5b: bytesPerTexLine = 16; break; default: throw new Exception("Unexpected format during volume texture plane fetching: " + Format + "."); } // skip to correct group inputStream.DiscardBytes(group * bytecount * 4u); // copy texture MemoryStream s = new MemoryStream((int)bytecount); for (uint i = 0; i < bytecount; i += bytesPerTexLine) { inputStream.DiscardBytes(texInGroupBefore * bytesPerTexLine); StreamUtils.CopyStream(inputStream, s, bytesPerTexLine); inputStream.DiscardBytes(texInGroupAfter * bytesPerTexLine); } return(s); }
private bool LoadFile(byte[] File) { this.File = File; FilePointers = new List <uint>(); int FileCount = BitConverter.ToUInt16(File, 0); for (int i = 0; i < FileCount + 1; ++i) { uint ptr = NumberUtils.ToUInt24(File, i * 3 + 2); FilePointers.Add(ptr); } return(true); }
public Stream GetSinglePlane_MipBeforeDepth(Stream inputStream, uint depthlevel) { Stream s = new MemoryStream(); uint planesBeforeCurrent = depthlevel; uint planesAfterCurrent = Depth - depthlevel - 1; uint sum = 0u; for (int i = 0; i < Mipmaps; ++i) { uint bytecount = GetByteCountSingleDepthPlane(i); sum += bytecount; } if (Format == TextureFormat.DXT1a || Format == TextureFormat.DXT1b || Format == TextureFormat.DXT5a || Format == TextureFormat.DXT5b) { // this feels stupid?? sum = NumberUtils.Align(sum, 0x80u); } inputStream.DiscardBytes(planesBeforeCurrent * sum); StreamUtils.CopyStream(inputStream, s, sum); inputStream.DiscardBytes(planesAfterCurrent * sum); return(s); }
public void CreateFromDirectory(string Dir, string Outfile) { string[] Filepaths = System.IO.Directory.GetFiles(Dir); ushort Filecount = (ushort)Filepaths.Length; uint RequiredBytesForHeader = NumberUtils.Align(Filecount * 4u + 4u, 0x50u); // pretty sure this is not right but should work var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create); // header Filestream.WriteByte((byte)'S'); Filestream.WriteByte((byte)'C'); Filestream.WriteByte((byte)'M'); Filestream.WriteByte((byte)'P'); uint TotalFilesize = RequiredBytesForHeader; foreach (string Path in Filepaths) { Filestream.Write(BitConverter.GetBytes(TotalFilesize), 0, 4); TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length); TotalFilesize = TotalFilesize.Align(0x10u); } while (Filestream.Length < RequiredBytesForHeader) { Filestream.WriteByte(0x00); } // files foreach (string Path in Filepaths) { var File = new System.IO.FileStream(Path, System.IO.FileMode.Open); StreamUtils.CopyStream(File, Filestream, (int)File.Length); File.Close(); while (Filestream.Length % 0x10 != 0) { Filestream.WriteByte(0x00); } } Filestream.Close(); }
public void CreateFromDirectory(string Dir, string Outfile) { string[] Filepaths = System.IO.Directory.GetFiles(Dir); ushort Filecount = (ushort)Filepaths.Length; uint RequiredBytesForHeader = NumberUtils.Align(Filecount * 3u + 5u, 0x10u); // 3 bytes per filesize + 3 bytes for an extra pointer to first file + 2 bytes for filecount var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create); // header Filestream.Write(BitConverter.GetBytes(Filecount), 0, 2); Filestream.Write(NumberUtils.GetBytesForUInt24(RequiredBytesForHeader), 0, 3); uint TotalFilesize = RequiredBytesForHeader; foreach (string Path in Filepaths) { TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length); Filestream.Write(NumberUtils.GetBytesForUInt24(TotalFilesize), 0, 3); TotalFilesize = TotalFilesize.Align(0x10u); } while (Filestream.Length < RequiredBytesForHeader) { Filestream.WriteByte(0x00); } // files foreach (string Path in Filepaths) { var File = new System.IO.FileStream(Path, System.IO.FileMode.Open); StreamUtils.CopyStream(File, Filestream, (int)File.Length); File.Close(); while (Filestream.Length % 0x10 != 0) { Filestream.WriteByte(0x00); } } Filestream.Close(); }
public void CreateFromDirectory(string Dir, string Outfile, string[] FileOrder) { List <string> Filepaths = new List <string>(); foreach (string f in FileOrder) { Filepaths.Add(System.IO.Path.Combine(Dir, f)); } var Filestream = new System.IO.FileStream(Outfile, System.IO.FileMode.Create); uint RequiredBytesForHeader; uint Filecount = (uint)Filepaths.Count; uint TotalFilesize; Xorbyte = 0x55; //Xorbyte = 0x00; // 0x20 Header + 0x28 per file RequiredBytesForHeader = NumberUtils.Align(Filecount * 0x28u + 0x20u, 0x20u); TotalFilesize = RequiredBytesForHeader; foreach (string Path in Filepaths) { TotalFilesize += (uint)(new System.IO.FileInfo(Path).Length); TotalFilesize = TotalFilesize.Align(0x20u); } // header Filestream.WriteByte((byte)'R'); Filestream.WriteByte((byte)'T'); Filestream.WriteByte((byte)'D'); Filestream.WriteByte((byte)'P'); Filestream.Write(BitConverter.GetBytes(RequiredBytesForHeader), 0, 4); Filestream.Write(BitConverter.GetBytes(Filecount), 0, 4); Filestream.Write(BitConverter.GetBytes(TotalFilesize), 0, 4); Filestream.WriteByte(Xorbyte); Filestream.WriteByte(0x28); Filestream.WriteByte(0x25); while (Filestream.Length < 0x20) { Filestream.WriteByte(0x00); } // header file info uint ptr = 0; foreach (string Path in Filepaths) { var fi = new System.IO.FileInfo(Path); uint size = (uint)(fi.Length); byte[] name = Encoding.ASCII.GetBytes(fi.Name); Filestream.Write(name, 0, Math.Min(0x20, name.Length)); for (int i = name.Length; i < 0x20; ++i) { Filestream.WriteByte(0x00); } Filestream.Write(BitConverter.GetBytes(size), 0, 4); Filestream.Write(BitConverter.GetBytes(ptr), 0, 4); ptr = NumberUtils.Align(ptr + size, 0x20u); } while (Filestream.Length < RequiredBytesForHeader) { Filestream.WriteByte(0x00); } // files foreach (string Path in Filepaths) { var File = new System.IO.FileStream(Path, System.IO.FileMode.Open); while (true) { int b = File.ReadByte(); if (b == -1) { break; } Filestream.WriteByte((byte)(b ^ Xorbyte)); } File.Close(); while (Filestream.Length % 0x20 != 0) { Filestream.WriteByte(0x00); } } Filestream.Close(); }