diff --git a/ciso.py b/ciso.py index bced6c3..8748be6 100755 --- a/ciso.py +++ b/ciso.py @@ -6,7 +6,11 @@ import os import struct import sys +import shutil +import math import lz4.frame +import json +import re CISO_MAGIC = 0x4F534943 # CISO CISO_HEADER_SIZE = 0x18 # 24 @@ -14,6 +18,11 @@ CISO_HEADER_FMT = ' 0xFFBF6000: # Create new file for the split - fout_2 = open(os.path.splitext(infile)[0] + '.2.cso', 'wb') + fout_2 = open(out_split_name + '.2.cso', 'wb') split_fout = fout_2 # Reset write position @@ -221,9 +235,605 @@ def compress_iso(infile): pad_file_size(fout_2) fout_2.close() +def split_iso(infile): + abs_infile = os.path.abspath(infile) + abs_outdir = get_output_dir(os.path.dirname(abs_infile)) + split_name = os.path.splitext(os.path.basename(abs_infile))[0] + out_split_name = abs_outdir + '/' + split_name + + # Replace file extension with .iso + fout_1 = open(out_split_name + '.1.iso', 'wb') + fout_2 = None + + with open(infile, 'rb') as fin: + print("Processing '{}'".format(infile)) + + # Detect and validate the ISO + detect_iso_type(fin) + + ciso = check_file_size(fin) + for k, v in ciso.items(): + print("{}: {}".format(k, v)) + + write_pos = fout_1.tell() + + # Progress counters + percent_period = ciso['total_blocks'] / 100 + percent_cnt = 0 + + split_fout = fout_1 + + for block in range(0, ciso['total_blocks']): + # Check if we need to split the ISO (due to FATX limitations) + # TODO: Determine a better value for this. + if write_pos > 0xFFBF6000: + # Create new file for the split + fout_2 = open(out_split_name + '.2.iso', 'wb') + split_fout = fout_2 + + # Reset write position + write_pos = 0 + + # Read raw data + raw_data = fin.read(ciso['block_size']) + raw_data_size = len(raw_data) + + # Next index + write_pos += raw_data_size + + # Write data + split_fout.write(raw_data) + + # Progress bar + percent = int(round((block / (ciso['total_blocks'] + 1)) * 100)) + if percent > percent_cnt: + update_progress((block / (ciso['total_blocks'] + 1))) + percent_cnt = percent + + print("\nDone") + + fout_1.close() + if fout_2: + fout_2.close() + +def process_iso(infile): + mode = get_compress_mode() + + if mode == 'ISO': + split_iso(infile) + else: + compress_iso(infile) + +def is_xbe_file(xbe, offset = 0): + if not os.path.isfile(xbe): + return False + + with open(xbe, 'rb') as xbe_file: + xbe_file.seek(offset) + magic = xbe_file.read(4) + + if magic != b'XBEH': + return False + + return True + +def get_iso_root_dir_offset_and_size(iso_file): + global image_offset + + iso_header_offset = 0x10000 + root_dir_sect_offset = 0x14 + + root_dir_offset = 0 + root_dir_size = 0 + + with open(iso_file, 'rb') as f: + detect_iso_type(f) + + f.seek(image_offset + iso_header_offset + root_dir_sect_offset) + root_dir_sect = struct.unpack('