Explorar el Código

ipf_align: New script to align all tracks of an IPF image file

Keir Fraser hace 5 años
padre
commit
033989cab8
Se han modificado 1 ficheros con 50 adiciones y 0 borrados
  1. 50 0
      scripts/misc/ipf_align.py

+ 50 - 0
scripts/misc/ipf_align.py

@@ -0,0 +1,50 @@
+# ipf_align.py
+# 
+# Align all tracks in an IPF image to the same offset from index mark.
+# 
+# Written & released by Keir Fraser <keir.xen@gmail.com>
+# 
+# This is free and unencumbered software released into the public domain.
+# See the file COPYING for more details, or visit <http://unlicense.org>.
+
+import struct, sys, crcmod.predefined
+
+def main(argv):
+    crc32 = crcmod.predefined.Crc('crc-32')
+    offset = 1024
+    if len(argv) == 4:
+        offset = int(argv[3])
+    elif len(argv) != 3:
+        print("%s <input_file> <output_file> [<offset>]" % argv[0])
+        return
+    with open(argv[1], "rb") as f:
+        in_dat = bytearray(f.read())
+    out_dat = bytearray()
+    while in_dat:
+        # Decode the common record header
+        id, length, crc = struct.unpack(">4s2I", in_dat[:12])
+        # Consume the record from the input array
+        record = in_dat[:length]
+        in_dat = in_dat[length:]
+        # Check the CRC
+        record[8:12] = bytes(4)
+        assert crc == crc32.new(record).crcValue, "CRC mismatch"
+        # Modify the record as necessary
+        if id == b'IMGE':
+            trkbits, = struct.unpack(">I", record[48:52])
+            if trkbits > offset:
+                record[32:40] = struct.pack(">2I", offset//8, offset)
+        # Re-calculate the CRC
+        record[8:12] = struct.pack(">I", crc32.new(record).crcValue)
+        # DATA chunk has extra data to copy
+        if id == b'DATA':
+            size, bsize, dcrc, datchunk = struct.unpack(">4I", record[12:28])
+            record += in_dat[:size]
+            in_dat = in_dat[size:]
+        # Write the full modified record into the output array
+        out_dat += record
+    with open(argv[2], "wb") as f:
+        f.write(out_dat)
+    
+if __name__ == "__main__":
+    main(sys.argv)