CloneCD: IMG/CCD/SUB (.img + .ccd + .sub)

CloneCD (Elaborate Bytes, 1999; later SlySoft/RedFox) was designed to copy CDs exactly, including the copy-protection tricks that defeated ordinary copying software. Its image format follows from that goal: it keeps every sector raw, keeps all subchannel data, and keeps the TOC exactly as the drive reported it. A CloneCD image has three files with the same base name:

File Format Contents
.img binary Raw 2352-byte sectors of every track, back to back, starting at LBA 0
.sub binary 96 bytes of subchannel per sector, linear (deinterleaved) layout, parallel to the .img
.ccd INI-style text The Full TOC (one [Entry] per lead-in Q entry), session info, per-track modes and indexes, CD-TEXT, MCN, ISRC

The format is CD-only. The .sub is optional: without it the image still loads, but loses everything that lives only in the subchannel. The format was never formally published. This description comes from libmirage, Aaru, psx-spx, and CCD files in the wild.


1. The .img file #

  • Sector size: always 2352 bytes (930h). Audio and data sectors are stored identically: everything the drive returned, including sync, header, subheader and EDC/ECC for data sectors.

  • Starts at LBA 0 (00:02:00). The 150-sector pregap of track 1 is not stored.

  • Contains every later track's pregap. CloneCD reads the disc sequentially, so index-0 areas between tracks are in the file. A single-session image is a contiguous dump from LBA 0 up to the lead-out:

    byte offset of LBA n = n × 2352            (single session)
    
  • No lead-out, no lead-in. On a multisession disc, the gap between sessions (lead-out of session n, lead-in of session n+1, pregap of its first track) is not stored. The next session's first track follows directly after the previous session's last sector.

  • Data sectors are normally descrambled, as the drive delivers them. If [Disc] DataTracksScrambled=1, data sectors are stored in their scrambled form (encoding §4). CloneCD used this when reading data tracks with audio-read commands (for drives or protections where that worked better). A reader must descramble them before use.

.img is also used for other things (plain 2048-byte ISO-style images, floppy images). A CloneCD .img is identified by its .ccd.

2. The .sub file #

  • 96 bytes per sector, one record per .img sector, in the same order:

    .sub offset of the record for .img sector k = k × 96
    
  • Layout: linear. 12 bytes of P, 12 bytes of Q, then R, S, T, U, V, W, each 12 bytes (96 bits, MSB first). See Subchannels §6.2.

    00h–0Bh  P   (all FF in pregaps, 00 in tracks; alternating in lead-out)
    0Ch–17h  Q   (bytes 0Ch–15h = Q data, 16h–17h = CRC-16)
    18h–23h  R
    ...
    54h–5Fh  W   (R–W usually zero, unless CD+G)
    
  • The data is stored as read, including any bad CRCs. That is the point: protections such as SafeDisc 2+, LaserLock, PlayStation LibCrypt and SecuROM rely on deliberately corrupted or shifted Q data.

Because the .sub uses the same indexing as the .img, the .img/.sub pair is often reused by other tools ("IMG/SUB" alongside a CUE).


3. The .ccd file #

An INI-style text file. Section names appear in square brackets. Keys are Name=value, one per line. Section and key names are case-insensitive in readers, though CloneCD writes them as shown. Lines that don't match are ignored.

Section order as written by CloneCD:

[CloneCD]
[Disc]
[CDText]          (only if the disc has CD-TEXT)
[Session 1]
[Session 2] ...
[Entry 0]
[Entry 1] ...     (one per TOC entry, numbered from 0)
[TRACK 1]
[TRACK 2] ...     (version 3 only)

3.1 [CloneCD] #

Key Meaning
Version File format version. 3 is the most common (CloneCD 3.x+); 2 is older and has no [TRACK] sections. Aaru rejects other values. Its writer produces version 2.

3.2 [Disc] #

Key Meaning
TocEntries Number of [Entry] sections (all lead-in entries of all sessions)
Sessions Number of sessions
DataTracksScrambled 0 normally; 1 = data sectors in the .img are stored scrambled
CDTextLength Total size of the CD-TEXT data in bytes = 18 × number of packs (0 if none)
CATALOG Optional 13-digit MCN (EAN/UPC barcode)

3.3 [CDText] #

[CDText]
Entries=24
Entry 0=80 00 00 00 41 6c 62 75 6d 20 54 69 74 6c 65 00
Entry 1=80 01 01 00 53 6f 6e 67 20 4f 6e 65 00 53 6f 6e
...
Key Meaning
Entries Number of CD-TEXT packs
Entry n Pack n as 16 hex bytes separated by spaces: the 4-byte header (pack type, track, sequence, block/char position) + 12 text bytes. The 2 CRC bytes are omitted.

libmirage checks that CDTextLength == Entries × 18: the length counts the CRC bytes even though they are not stored. It allocates 18 bytes per pack and leaves the CRC zero. The pack format is described on the Subchannels page.

3.4 [Session n] #

Key Meaning
PreGapMode The sector mode of the session's first pregap: 0 = audio, 1 = Mode 1, 2 = Mode 2 (Aaru writes it from the first track's type). Needed to synthesise the 150 missing sectors of the first pregap correctly.
PreGapSubC Unknown; 0 or 1. Probably whether subchannel for the pregap should be synthesised (Aaru always writes 0)

3.5 [Entry n]: one Full TOC entry each #

Each [Entry] is one lead-in Q entry, as returned by READ TOC format 2 (Full TOC). That means one entry per track pointer, plus A0, A1, A2 for each session, plus any ADR 5 pointers (B0, C0, …).

Key Meaning Full TOC field
Session Session this entry belongs to Session number
Point 0x01–0x63 = track, 0xa0 = first track, 0xa1 = last track, 0xa2 = lead-out, 0xb0, 0xc0, … (hex) POINT
ADR Q mode, hex (0x01 normally, 0x05 for B0/C0) ADR
Control Control nibble, hex (0x04 = data, 0x00 = audio, …) CONTROL
TrackNo TNO; always 0 in the lead-in TNO
AMin, ASec, AFrame Min/Sec/Frame: lead-in running time, or for B0 the next program area Min, Sec, Frame
ALBA AMin:ASec:AFrame converted to an LBA (may be negative) (derived)
Zero The Zero byte (DDCD: hour digits; Aaru writes `(HOUR<<4) PHOUR`)
PMin, PSec, PFrame PMIN/PSEC/PFRAME: track start, first/last track number + disc type, lead-out start, etc. PMIN, PSEC, PFRAME
PLBA PMin:PSec:PFrame converted to an LBA (derived)

All values are decimal except where shown in hex. MSF values are binary (not BCD).

ALBA and PLBA are derived values: LBA = (min × 60 + sec) × 75 + frame − 150, with lead-in values wrapping negative (LBA §4). They are often meaningless (A0's "PLBA" of 4350 simply means PMin=1, PSec=0 → 1:00:00 − 150). Readers should use the MSF fields, and use PLBA only for track pointers and A2. Drives normally return zero for the A-time in Full TOC, so most CCDs show AMin=0, ASec=0, AFrame=0, ALBA=-150.

Typical values of PLBA for the special points: A0 → 4350 (PMin 1 = first track 1, PSec 0 = CD-DA/CD-ROM) or 6750 (PSec 32 = 0x20 = CD-ROM XA); A1 → (last track × 4500) − 150.

3.6 [TRACK n] (version 3) #

Key Meaning
MODE 0 = audio, 1 = Mode 1, 2 = Mode 2
INDEX 0 LBA of index 0 (pregap start), if the track has a pregap. Usually missing for track 1
INDEX 1 LBA of index 1 (track start; equals the track's PLBA)
INDEX 2… Further indexes, if found (Aaru reads them; libmirage reads only 0 and 1)
ISRC Optional 12-character ISRC

There is no flags key. A track's CONTROL bits come from its [Entry].

libmirage observed that MODE is sometimes wrong, so it ignores it and determines each track's mode from the sector data (sync + header byte 15; no sync means audio). Aaru uses MODE but refines Mode 2 into Form 1/Form 2/formless by inspecting the subheader.

libmirage also suspects that INDEX values on later sessions may be session-relative. It only ever uses their differences (pregap = INDEX 1 − INDEX 0), together with PLBA, so either interpretation works.


4. Example #

The Mixed Mode disc from the Tracks page: track 1 Mode 1, tracks 2–4 audio, lead-out at 24:50:00.

[CloneCD]
Version=3
[Disc]
TocEntries=7
Sessions=1
DataTracksScrambled=0
CDTextLength=0
[Session 1]
PreGapMode=1
PreGapSubC=0
[Entry 0]
Session=1
Point=0xa0
ADR=0x01
Control=0x04
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=1
PSec=0
PFrame=0
PLBA=4350
[Entry 1]
Session=1
Point=0xa1
ADR=0x01
Control=0x00
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=4
PSec=0
PFrame=0
PLBA=17850
[Entry 2]
Session=1
Point=0xa2
ADR=0x01
Control=0x00
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=24
PSec=50
PFrame=0
PLBA=111600
[Entry 3]
Session=1
Point=0x01
ADR=0x01
Control=0x04
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=0
PSec=2
PFrame=0
PLBA=0
[Entry 4]
Session=1
Point=0x02
ADR=0x01
Control=0x00
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=12
PSec=24
PFrame=4
PLBA=55654
[Entry 5]
Session=1
Point=0x03
ADR=0x01
Control=0x00
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=16
PSec=1
PFrame=50
PLBA=71975
[Entry 6]
Session=1
Point=0x04
ADR=0x01
Control=0x00
TrackNo=0
AMin=0
ASec=0
AFrame=0
ALBA=-150
Zero=0
PMin=20
PSec=46
PFrame=10
PLBA=93310
[TRACK 1]
MODE=1
INDEX 1=0
[TRACK 2]
MODE=0
INDEX 0=55504
INDEX 1=55654
[TRACK 3]
MODE=0
INDEX 1=71975
[TRACK 4]
MODE=0
INDEX 0=93160
INDEX 1=93310

The matching files are:

  • .img = 111,600 sectors × 2352 = 262,483,200 bytes (LBA 0 up to the lead-out);
  • .sub = 111,600 × 96 = 10,713,600 bytes.

Track 2's index 0 begins at .img offset 55,504 × 2352 and its index 1 at 55,654 × 2352: the pregap is in the file.

A multisession CCD has Sessions=2, [Session 2], and more entries: A0/A1/A2 for session 2 with Session=2, and in session 1 usually B0 (ADR 5) and C0 (ADR 5) entries. See Sessions §4.


5. How a reader builds the disc #

libmirage's algorithm (lib/cdemu/libmirage/images/image-ccd/parser.c):

  1. Parse all sections into structures. Key regexes are anchored per section, and a line that fails the current section's rules is tried against section headers.
  2. Drop entries that aren't A0, A2 or a track (A1, B0, C0, … are discarded for layout purposes).
  3. Sort by session; within a session put A0 first, tracks by number, then A2.
  4. Walk the list, keeping a running sector offset into the .img/.sub, starting at 0:
    • A0: start a new session. Session type from PSec (00h CD-ROM, 10h CD-i, 20h CD-ROM XA). Apply CATALOG as the MCN.
    • Track entry: create the track, and a fragment reading the .img at offset × 2352 and the .sub at offset × 96 (linear PW96, external file).
      • Determine the mode by reading the first sector (sync + mode byte).
      • Pregap = INDEX 1 − INDEX 0 (or INDEX 1 alone for the first track of a session, if set).
      • Length = (next entry's PLBA − next pregap) − (this PLBA − this pregap). The "next entry" can be the session's A2, so the last track runs to the lead-out.
      • offset += length.
    • A2 with more entries following: the session has ended, so set its lead-out length to 11,250 (session 1) or 6,750 (later): the lead-out plus the next lead-in, neither of which is in the .img.
  5. If [CDText] was present, decode the packs into session 1.
  6. Guess the medium type and add the standard 150-sector Red Book pregap before track 1.

Aaru's reader (lib/Aaru/Aaru.Images/CloneCD/Read.cs) instead walks the Full TOC in order. It uses ADR 1/4 entries for A0 (disc type), A2 (lead-out) and track starts, ADR 5 C0 for the media manufacturer (from ATIP, when PMIN = 97), and ADR 6 for a disc ID. It derives Data/Audio from Control & 0x0D, and refines the type from MODE and the sector contents.


6. Strengths and limits #

Preserved Not preserved
Every sector raw (2352 bytes), including intentional EDC/ECC errors The lead-in and lead-out themselves (only the TOC is kept)
All 96 subchannel bytes per sector (with .sub) The first 150 sectors (track 1 pregap) and the data of multisession gaps
The complete Full TOC, including ADR 5 entries, exactly as reported DVDs (the format is CD-only)
Multisession DPM / physical timing
CD-TEXT (all packs), MCN, ISRC C2 error information; drive read offsets (unless corrected when dumping)
Optional scrambled storage of data tracks

Compared with BIN/CUE, CloneCD keeps subchannel and the real TOC. Compared with MDS/MDF it keeps CD-TEXT and has a simpler, documented-by-example text descriptor, but it cannot hold DVDs or DPM.


Sources #