private Stream Decompress(Stream input) { using var br = new BinaryReaderX(input, true); input.Position = 5; var magic = br.ReadString(4); if (magic != "F3XT") { _wasCompressed = false; return(input); } _wasCompressed = true; var ms = new MemoryStream(); input.Position = 0; _compMethod = NintendoCompressor.PeekCompressionMethod(input); NintendoCompressor.Decompress(input, ms); ms.Position = 0; return(ms); }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { var fileStream = await fileSystem.OpenFileAsync(filePath); // Decompress, if necessary using var br = new BinaryReaderX(fileStream, true); fileStream.Position = 9; if (br.ReadString(4) == "nns_") { _wasCompressed = true; fileStream.Position = 0; var decompressedStream = new MemoryStream(); NintendoCompressor.Decompress(fileStream, decompressedStream); fileStream.Close(); fileStream = decompressedStream; } fileStream.Position = 0; Images = new List <IKanvasImage> { new KanvasImage(EncodingDefinition, _img.Load(fileStream)) }; }
public static ArchiveFileInfo CreateAfi(Stream file, string fileName) { var compressionIdent = file.ReadByte(); var isCompressed = compressionIdent == 0x10 || compressionIdent == 0x11 || compressionIdent == 0x24 || compressionIdent == 0x28 || compressionIdent == 0x30; file.Position--; if (!isCompressed) { return(new ArchiveFileInfo(file, fileName)); } var sizeBuffer = new byte[4]; file.Read(sizeBuffer, 0, 4); file.Position = 0; var method = (NintendoCompressionMethod)(BinaryPrimitives.ReadUInt32LittleEndian(sizeBuffer) & 0xFF); var decompressedSize = BinaryPrimitives.ReadUInt32LittleEndian(sizeBuffer) >> 8; if (decompressedSize <= file.Length) { return(new ArchiveFileInfo(file, fileName)); } return(new ArchiveFileInfo(file, fileName, NintendoCompressor.GetConfiguration(method), decompressedSize)); }
public IList <IArchiveFileInfo> Load(Stream incStream, Stream datStream, string version) { using var incBr = new BinaryReaderX(incStream); var entryCount = (int)(incStream.Length / FileEntrySize); var entries = incBr.ReadMultiple <AAPackFileEntry>(entryCount); var nameMapping = AAPackSupport.GetMapping(version); var result = new IArchiveFileInfo[entryCount]; for (var i = 0; i < entryCount; i++) { var subStream = new SubStream(datStream, entries[i].offset, entries[i].compSize); var compressionMethod = NintendoCompressor.PeekCompressionMethod(subStream); var fileName = $"{i:00000000}.bin"; if (nameMapping.ContainsKey(entries[i].hash)) { fileName = nameMapping[entries[i].hash]; } result[i] = new AAPackArchiveFileInfo(subStream, fileName, NintendoCompressor.GetConfiguration(compressionMethod), entries[i].uncompSize, entries[i]); } return(result); }
private IList <ChnkSection> ReadSections(BinaryReaderX br) { // Read raw chunks var chunks = new List <ChnkSection>(); while (br.BaseStream.Position < br.BaseStream.Length) { chunks.Add(br.ReadType <ChnkSection>()); } // Decompress chunk data foreach (var chunk in chunks) { if (chunk.decompressedSize == 0) { continue; } var ms = new MemoryStream(); NintendoCompressor.Decompress(new MemoryStream(chunk.data), ms); ms.Position = 0; chunk.data = ms.ToArray(); } return(chunks); }
private IArchiveFileInfo CreateAfi(Stream file, string name) { file.Position = 0; var method = NintendoCompressor.PeekCompressionMethod(file); var size = NintendoCompressor.PeekDecompressedSize(file); return(new ArchiveFileInfo(file, name, NintendoCompressor.GetConfiguration(method), size)); }
private Stream Decompress(Stream input) { var output = new MemoryStream(); NintendoCompressor.Decompress(input, output); output.Position = 0; return(output); }
private IArchiveFileInfo CreateAfi(Stream file, string name, TarcEntry entry) { if (entry.compSize != 0 && entry.compSize != entry.decompSize) { var method = NintendoCompressor.PeekCompressionMethod(file); return(new TarcArchiveFileInfo(file, name, entry, NintendoCompressor.GetConfiguration(method), entry.decompSize)); } return(new TarcArchiveFileInfo(file, name, entry)); }
private IArchiveFileInfo CreateAfi(Stream input, string fileName, PackEntry entry) { var method = NintendoCompressor.PeekCompressionMethod(input); if (!NintendoCompressor.IsValidCompressionMethod(method)) { return(new PackArchiveFileInfo(input, fileName, entry)); } return(new PackArchiveFileInfo(input, fileName, entry, NintendoCompressor.GetConfiguration(method), NintendoCompressor.PeekDecompressedSize(input))); }
private IArchiveFileInfo CreateAfi(Stream file, string fileName, Gk2Arc1Entry entry) { if (!entry.IsCompressed) { return(new Gk2Arc1ArchiveFileInfo(file, fileName, entry)); } file.Position = 0; var compression = NintendoCompressor.PeekCompressionMethod(file); var decompressedSize = NintendoCompressor.PeekDecompressedSize(file); return(new Gk2Arc1ArchiveFileInfo(file, fileName, entry, NintendoCompressor.GetConfiguration(compression), decompressedSize)); }
public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext) { var fileStream = _wasCompressed ? new MemoryStream() : fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); _img.Save(fileStream, Images[0].ImageInfo); if (_wasCompressed) { var compStream = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); fileStream.Position = 0; NintendoCompressor.Compress(fileStream, compStream, _compMethod); } return(Task.CompletedTask); }
public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext) { var fileStream = await fileSystem.OpenFileAsync(filePath); if (IsCompressed(fileStream)) { _method = NintendoCompressor.PeekCompressionMethod(fileStream); } if (_method != null) { fileStream = Decompress(fileStream); } Images = new List <IKanvasImage> { new KanvasImage(EncodingDefinition, _raw.Load(fileStream)) }; }
public IList <IArchiveFileInfo> Load(Stream dataStream, Stream matStream) { using var br = new BinaryReaderX(dataStream, true); using var matBr = new BinaryReaderX(matStream); // Read entries var entries = matBr.ReadMultiple <SarEntry>((int)(matStream.Length / EntrySize)); // Read header _header = br.ReadType <SarContainerHeader>(); // Add files var result = new List <IArchiveFileInfo>(); for (var i = 0; i < entries.Count; i++) { var entry = entries[i]; dataStream.Position = entry.offset; // Read compression header var compHeader = br.ReadType <SarContainerHeader>(); if (compHeader.magic != "cmp ") { result.Add(new SarArchiveFileInfo(new SubStream(dataStream, entry.offset, entry.size), $"{i:00000000}.bin")); continue; } compHeader = br.ReadType <SarContainerHeader>(); if (compHeader.magic != "lz7 ") { throw new InvalidOperationException($"Unknown compression container detected for file at index {i}."); } var fileStream = new SubStream(dataStream, entry.offset + 0x18, SarSupport.GetCompressedSize(dataStream, entry.offset + 0x18, compHeader.data2)); var name = $"{i:00000000}.bin"; var compMethod = NintendoCompressor.PeekCompressionMethod(fileStream); result.Add(new SarArchiveFileInfo(fileStream, name, NintendoCompressor.GetConfiguration(compMethod), NintendoCompressor.PeekDecompressedSize(fileStream))); } return(result); }
public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext) { var fileStream = _method != null ? new MemoryStream() : fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); _raw.Save(fileStream, Images[0].ImageInfo); if (_method == null) { return(Task.CompletedTask); } var output = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write); fileStream.Position = 0; NintendoCompressor.Compress(fileStream, output, _method.Value); return(Task.CompletedTask); }
public IList <IArchiveFileInfo> Load(Stream input) { using var br = new BinaryReaderX(input, true); var offsets = new List <long>(); while (br.BaseStream.Position < br.BaseStream.Length) { var headerMagic = br.ReadString(6); if (headerMagic == "3DS-LZ") { offsets.Add(br.BaseStream.Position + 2); } br.BaseStream.Position += 0x3A; } _sizes = new int[offsets.Count]; for (var i = 0; i < offsets.Count; i++) { var endOffset = i + 1 == offsets.Count ? input.Length : (offsets[i + 1] - 8); _sizes[i] = (int)(endOffset - offsets[i]); } // Add files var result = new ArchiveFileInfo[offsets.Count]; for (var i = 0; i < offsets.Count; i++) { var subStream = new SubStream(input, offsets[i], _sizes[i]); var compressionMethod = NintendoCompressor.PeekCompressionMethod(subStream); var decompressedSize = NintendoCompressor.PeekDecompressedSize(subStream); result[i] = new ArchiveFileInfo(subStream, $"{i:00000000}{_3dsLzSupport.DetermineExtension(subStream)}", NintendoCompressor.GetConfiguration(compressionMethod), decompressedSize); } return(result); }