Last active
January 4, 2023 10:52
-
-
Save shimamura-sakura/8316a245232bbe781653f300e795c3e2 to your computer and use it in GitHub Desktop.
Decompress .lzs files from Kanda Alice mo Suiri suru (神田アリスも推理スル). I think they are mostly BNTX files (Nintendo Switch BNTX).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
const mem = std.mem; | |
const hea = std.heap.page_allocator; | |
pub fn main() !void { | |
const stderr = std.io.getStdErr().writer(); | |
const argv = try std.process.argsAlloc(hea); | |
defer std.process.argsFree(hea, argv); | |
if (argv.len < 3) | |
return stderr.print("usage: '{s}' input_lzs output_file\n", .{argv[0]}); | |
const file_i = try std.fs.cwd().openFileZ(argv[1], .{}); | |
defer file_i.close(); | |
const file_o = try std.fs.cwd().createFileZ(argv[2], .{}); | |
defer file_o.close(); | |
var bfReader = std.io.bufferedReader(file_i.reader()); | |
const reader = bfReader.reader(); | |
const header = try reader.readBytesNoEof(12); | |
const decmp_length = mem.readIntLittle(u32, header[0..4]); | |
const input_length = mem.readIntLittle(u32, header[4..8]); | |
const escaped_byte = header[8]; | |
try stderr.print( | |
"output: {}, input: {}, escape: 0x{x:0>2}\n", | |
.{ decmp_length, input_length, escaped_byte }, | |
); | |
const decmp_buffer = try hea.alloc(u8, decmp_length); | |
defer hea.free(decmp_buffer); | |
var decmp_offset: usize = 0; | |
while (decmp_offset < decmp_length) { | |
const b0 = try reader.readByte(); | |
const b1 = if (b0 == escaped_byte) try reader.readByte() else 0; | |
if (b0 != escaped_byte or b1 == b0) { | |
decmp_buffer[decmp_offset] = b0; | |
decmp_offset += 1; | |
} else { | |
const copy_off = if (b1 > escaped_byte) b1 - 1 else b1; | |
const copy_len = try reader.readByte(); | |
mem.copyBackwards( | |
u8, | |
decmp_buffer[decmp_offset .. decmp_offset + copy_len], | |
decmp_buffer[decmp_offset - copy_off .. decmp_offset - copy_off + copy_len], | |
); | |
decmp_offset += copy_len; | |
} | |
} | |
if (reader.readByte() != error.EndOfStream) | |
try stderr.print("warning: extra data after body", .{}); | |
try file_o.writeAll(decmp_buffer); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment