Created
August 23, 2017 04:37
-
-
Save NWPlayer123/05dd55dd1cce6eb5457741ce14f48587 to your computer and use it in GitHub Desktop.
Yaz0 decompression, written in python
This file contains hidden or 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
| from struct import unpack | |
| import sys | |
| with open(sys.argv[1], "rb") as f: | |
| base = ".".join(sys.argv[1].split(".")[:-1]) | |
| with open(base + ".sarc", "wb+") as o: | |
| assert f.read(4) == b"Yaz0" | |
| unc_size = unpack(">I", f.read(4))[0] | |
| o.write("\x00" * unc_size) #pre-allocate | |
| o.seek(0);f.seek(16) | |
| mask = 0 | |
| while unc_size != 0: | |
| if not mask: #read new flag byte | |
| mask = 0x80 | |
| flag = ord(f.read(1)) | |
| if flag & mask: #read one byte | |
| o.write(f.read(1)) | |
| unc_size -= 1 | |
| else: #RLE stuff | |
| code = (ord(f.read(1)) << 8) | ord(f.read(1)) | |
| back = (code & 0xFFF) + 1 | |
| if code >> 12: | |
| size = (code >> 12) + 2 | |
| else: #read third byte | |
| size = ord(f.read(1)) + 0x12 | |
| unc_size -= size | |
| if size > back: #overlap, cache it | |
| o.seek(back * -1, 1) | |
| buff = list(o.read(size + back)) | |
| for i in range(size): | |
| buff[back + i] = buff[i] | |
| o.seek((size + back) * -1, 1) | |
| o.write("".join(buff)) | |
| else: | |
| o.seek(back * -1, 1) | |
| data = o.read(size) | |
| o.seek(back - size, 1) | |
| o.write(data) | |
| mask >>= 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment