89 lines
3.0 KiB
Python
89 lines
3.0 KiB
Python
import argparse
|
|
import os
|
|
|
|
from compress import compress_data
|
|
|
|
|
|
class ApplicationError(Exception):
|
|
pass
|
|
|
|
|
|
def read_input_file(input_name, skip):
|
|
try:
|
|
with open(input_name, "rb") as ifp:
|
|
# determine input size
|
|
ifp.seek(0, os.SEEK_END)
|
|
input_size = ifp.tell()
|
|
ifp.seek(0, os.SEEK_SET)
|
|
|
|
if input_size == 0:
|
|
raise ApplicationError("Empty input file")
|
|
|
|
if skip >= input_size:
|
|
raise ApplicationError("Skip value exceeds input file size")
|
|
|
|
input_data = bytearray(input_size)
|
|
read_count = ifp.readinto(input_data)
|
|
|
|
if read_count != input_size:
|
|
raise ApplicationError("Cannot read input file")
|
|
|
|
except FileNotFoundError:
|
|
print(f"Error: Cannot access input file {input_name}")
|
|
exit(1)
|
|
except ApplicationError as e:
|
|
print(f"Error: {e}")
|
|
exit(1)
|
|
return input_data
|
|
|
|
|
|
def write_output_file(output_name, output_data):
|
|
with open(output_name, "wb") as ofp:
|
|
ofp.write(output_data)
|
|
ofp.close()
|
|
|
|
|
|
def write_summary(backwards_mode, delta, input_data, output_data, skip):
|
|
text_backwards = " backwards" if backwards_mode else ""
|
|
initial_size = len(input_data) - skip
|
|
output_size = len(output_data)
|
|
print(
|
|
f"File compressed{text_backwards} from {initial_size} to {output_size} bytes! (delta {delta})")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description='pyZX0 v2.2: Python port of ZX0 compressor by Einar Saukas for the same version.')
|
|
parser.add_argument('-f', action='store_true', help='Force overwrite of output file', dest='forced_mode')
|
|
parser.add_argument('-c', action='store_true', help='Classic file format (v1.*)', dest='classic_mode')
|
|
parser.add_argument('-b', action='store_true', help='Compress backwards', dest='backwards_mode')
|
|
parser.add_argument('-q', action='store_true', help='Quick non-optimal compression', dest='quick_mode')
|
|
parser.add_argument('-s', type=int, help='Skip first N bytes of input file', dest='skip')
|
|
parser.add_argument('input_name', type=str, help='Input file')
|
|
parser.add_argument('output_name', type=str, nargs='?', help='Output file')
|
|
|
|
args = parser.parse_args()
|
|
|
|
forced_mode = args.forced_mode
|
|
classic_mode = args.classic_mode
|
|
backwards_mode = args.backwards_mode
|
|
quick_mode = args.quick_mode
|
|
skip = args.skip if args.skip else 0
|
|
output_name = args.output_name if args.output_name else args.input_name + ".zx0"
|
|
|
|
input_data = read_input_file(args.input_name, skip)
|
|
|
|
if not forced_mode and os.path.exists(output_name):
|
|
raise ApplicationError(f"Already existing output file {output_name}")
|
|
|
|
output_data, delta = compress_data(input_data, skip, backwards_mode, classic_mode, quick_mode)
|
|
|
|
write_output_file(output_name, output_data)
|
|
write_summary(backwards_mode, delta, input_data, output_data, skip)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|