#!/usr/bin/env python3 # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT """rawCd.py - read data out of a raw CD image (2352-byte sectors, as CloneCD's .img and a .bin keep them). rawCd.py track IMAGE FIRST COUNT OUT COUNT Mode 1 sectors from FIRST (a track's start, as the image's .ccd or .cue gives it), their 2048 data bytes each, into OUT: the track as a plain image (an ISO 9660 or a BFS volume, say) rawCd.py eltorito ISO OUT the boot image an El Torito ISO boots with floppy emulation, 1.44 MB, into OUT; the ISO is 2048-byte sectors (such as a track `track` made), or a raw image whose first track is the ISO Read-only on its inputs. """ import struct import sys RAW_SECTOR = 2352 RAW_SYNC = b"\x00" + b"\xff" * 10 + b"\x00" # how every raw sector starts MODE1_DATA_AT = 16 # 12 sync bytes, 4 header bytes DATA_SECTOR = 2048 BOOT_RECORD_SECTOR = 17 # ISO 9660's El Torito boot record volume descriptor CATALOG_POINTER_AT = 0x47 # in the boot record: the boot catalog's sector DEFAULT_ENTRY_AT = 32 # in the catalog: after the validation entry BOOTABLE = 0x88 MEDIA_FLOPPY_144 = 2 LOAD_RBA_AT = 8 FLOPPY_144_BYTES = 1474560 def eltorito(iso, out): with open(iso, "rb") as f: raw = f.read(len(RAW_SYNC)) == RAW_SYNC record = readData(f, raw, BOOT_RECORD_SECTOR, DATA_SECTOR) if record[1:6] != b"CD001" or b"EL TORITO" not in record[7:39]: sys.exit("rawCd: %s has no El Torito boot record" % iso) catalog = struct.unpack_from("