Skip to content

api reference

Peterson Fernandes edited this page Aug 19, 2026 · 1 revision

API Reference

Complete reference for the public API of the CHDSharp package. All types live in the CHDSharp namespace (models in CHDSharp.Models, address helpers in CHDSharp.Utils).


Chd — static class

Entry point for verification, quick checks, and global settings.

Member Signature Description
LoggerFactory static ILoggerFactory? Set to enable internal logging. See Logging.
TaskCount static int (default 8) Number of parallel workers for CheckFile (1–64). Set before calling.
CheckFile static ChdResult CheckFile(Stream s, string filename, bool deepCheck, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Verify a standalone CHD. deepCheck: true decompresses every hunk and validates hashes; false is header-only. Reports progress per hunk when progress is supplied. Throws OperationCanceledException when cancelled.
CheckFile static ChdError CheckFile(Stream, string, bool, out uint? version, out byte[]? sha1, out byte[]? md5, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Out-parameter variant.
CheckFileWithParent static ChdResult CheckFileWithParent(string filename, string? parentFilename, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Verify a (possibly child) CHD, resolving parent references. Pass null for standalone. Single-threaded.
CheckFileWithParent static ChdError CheckFileWithParent(string, string?, out uint?, out byte[]?, out byte[]?, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Out-parameter variant.
IsChdFile static bool IsChdFile(string) / static bool IsChdFile(string, out uint version) Quick magic/version sniff. Never throws.
CheckHeader static bool CheckHeader(Stream, out uint length, out uint version) Validate signature + version; stream must be at position 0.
ReadHeader static ChdError ReadHeader(string, out ChdHeaderInfo? header) Parse the full header DTO from disk without keeping the file open (libchdr chd_read_header parity).
ReadHeader static ChdError ReadHeader(Stream, out ChdHeaderInfo? header) Header DTO from an existing seekable stream (stream left open).
ReadHeaderAsync static Task<(ChdError, ChdHeaderInfo?)> ReadHeaderAsync(string) Async variant.
Classify static ChdError Classify(string, out string? classification) Classify as "cd", "dvd", "hdd", "gd-rom", or null (unknown).

ChdFile — random-access reader

public sealed class ChdFile : IDisposable, IAsyncDisposable

Open a CHD once, then read hunks or byte ranges on demand. Not thread-safe — serialize all calls on one instance.

Static factory methods

Overload Description
Open(string path, out ChdFile? chd, CancellationToken ct = default) Standalone CHD from disk.
Open(string path, string parentPath, out ChdFile? chd, CancellationToken ct = default) Child CHD; the parent is opened internally and owned by the child.
Open(string path, ChdFile? parent, out ChdFile? chd, CancellationToken ct = default) Child with an external parent instance (caller keeps ownership; may be shared). Pass null for standalone.
Open(Stream stream, bool leaveOpen, out ChdFile? chd, CancellationToken ct = default) From any seekable readable stream.
Open(Stream stream, bool leaveOpen, ChdFile? parent, out ChdFile? chd, CancellationToken ct = default) From a stream with an external parent.
OpenAsync(...) Async twins of all five overloads above, each taking an optional trailing CancellationToken.

All overloads seek from the start. Failure codes: Chderrfilenotfound, Chderrcannotopenfile, Chderrinvalidparameter, Chderrinvalidfile, Chderrreaderror, Chderrrequiresparent, Chderrinvalidparent, Chderrunsupportedversion, Chderrinvaliddata. Cancellation throws OperationCanceledException.

Instance methods

Method Signature Description
ReadHunk ChdError ReadHunk(uint hunknum, byte[] buffer, CancellationToken ct = default) Decompress one hunk into buffer (≥ HunkBytes). Serves cached hunks when CacheSize > 1. Throws OperationCanceledException when cancelled.
Read ChdError Read(ulong byteOffset, byte[] destination, int destinationOffset, int count, CancellationToken ct = default) Read an arbitrary byte range, crossing hunk boundaries. Caches the last hunk. Throws OperationCanceledException when cancelled.
ReadSector ChdError ReadSector(uint lba, byte[] buffer, CancellationToken ct = default) Read the 2352-byte sector data at an LBA (CD/GD-ROM only). LBA 0 = the first track's INDEX 01 (MSF 00:02:00), mapped through the track table: PreGap frames into the image when the pregap is stored physically (metadata PGTYPE:V...), image frame 0 otherwise. Sub-2352 data sizes are zero-padded as stored. Chderrinvaliddata for non-disc images, Chderrinvalidparameter for too-small buffers or out-of-range addresses.
ReadSectorMsf ChdError ReadSectorMsf(byte m, byte s, byte f, byte[] buffer, CancellationToken ct = default) Read the 2352-byte sector at a BCD MSF address ((0x00, 0x02, 0x00) = LBA 0). Addresses before 00:02:00 are rejected with Chderrinvalidparameter.
ReadFrame ChdError ReadFrame(uint lba, byte[] buffer, CancellationToken ct = default) Read the full 2448-byte frame (2352-byte sector data + 96-byte subcode, zero-filled when unstored) at an LBA. Buffer ≥ UnitBytes. Same mapping and error codes as ReadSector.
ReadAllBytes ChdError ReadAllBytes(out byte[] data, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Decompress the whole image into one array. Reports per hunk when progress is supplied. Chderroutofmemory if the image exceeds 2 GiB. Throws OperationCanceledException when cancelled.
ConfigureCache void ConfigureCache(int maxHunks) Set the multi-hunk LRU cache size (decompressed hunks retained). <= 1 disables it (single-slot behaviour). See CacheSize.
Precache ChdError Precache() Read the entire compressed file into memory; subsequent hunk reads are served from RAM. Idempotent; restores stream position; Chderroutofmemory for files > 2 GiB, Chderrreaderror on IO failure.
ReadAllBytes ChdError ReadAllBytes(out byte[] data) Decompress the whole image into one array. Chderroutofmemory if the image exceeds 2 GiB.
EnumerateHunks IEnumerable<byte[]> EnumerateHunks(IProgress<ChdProgress>? progress = null) Yield each decompressed hunk in order. The array is reused — copy it if you need to keep it. Throws InvalidDataException on failure. Reports per hunk when progress is supplied.
ReadHunkAsync Task<ChdError> ReadHunkAsync(uint, byte[], CancellationToken ct = default) Async hunk read; cancelled via the token.
ReadAsync Task<ChdError> ReadAsync(ulong, byte[], int, int, CancellationToken ct = default) Async byte-range read; cancelled via the token.
GetMetadata ChdError GetMetadata(string? tag, uint index, out ChdMetadataEntry? entry) Search metadata by 4-char tag and occurrence index; null/empty tag = wildcard. Returns Chderrmetadatanotfound when absent.
GenerateCueSheet string GenerateCueSheet(string binFileName) CUE sheet (single-bin) for CD CHDs.
GenerateGdiDescriptor string GenerateGdiDescriptor(string[] trackFiles) GDI descriptor for GD-ROM CHDs.
ExportToc string ExportToc() Human-readable TOC dump.
ExtractToDirectory List<string> ExtractToDirectory(string outputDir, string baseFileName, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Extract to files; returns created paths. Throws InvalidDataException on track failures. Reports per hunk when progress is supplied; throws OperationCanceledException when cancelled.
ExtractToDirectoryWithReporting ExtractResult ExtractToDirectoryWithReporting(string outputDir, string baseFileName, IProgress<ChdProgress>? progress = null, CancellationToken ct = default) Reporting variant (per-track results, no exceptions). Cancellation still throws OperationCanceledException.
Dispose / DisposeAsync Release the stream (unless leaveOpen) and any internally-owned parent.

Properties

Property Type Description
Version uint CHD format version (1–5).
TotalBytes ulong Decompressed image size.
HunkBytes uint Size of one hunk.
CacheSize int Number of decompressed hunks retained by the multi-hunk LRU cache (default 1). Set via ConfigureCache(int). Memory capped at CacheSize * HunkBytes.
MaxCompressedBlockBytes uint Max allowed on-disk length of one compressed hunk. Defaults to HunkBytes * 2; a hunk claiming more is rejected with Chderrinvaliddata before allocation (OOM guard). Settable; floors at HunkBytes, set to 0 to reset.
HunkCount uint Total number of hunks.
UnitBytes uint Unit size for parent-block translation. V5: from header; V1–V4: derived from metadata (GDDD BPS, CD frame 2448, or HunkBytes).
Sha1 byte[]? Combined SHA1 (raw data + checksummed metadata).
RawSha1 byte[]? SHA1 of the raw image data only.
Md5 byte[]? MD5 of the raw image (V1–V3).
RequiresParent bool True if this is a differential child.
IsChild bool Alias for RequiresParent.
Tracks IReadOnlyList<ChdTrackInfo>? CD/GD-ROM track layout; null for non-disc images.
IsCd bool CD-ROM track metadata present.
IsGdRom bool GD-ROM (Sega Dreamcast) image.
IsLittleEndianAudio bool True for legacy GD-ROMs (detected by the CHGT tag / CD_FLAG_GDROMLE) whose CDDA audio tracks are stored little-endian. AUDIO tracks are byte-swapped to big-endian order when extracted.
IsDvd bool DVD metadata present.
IsHdd bool Hard-disk geometry metadata present (V1/V2: via synthesized GDDD).
Metadata IReadOnlyList<ChdMetadataEntry> All metadata entries, lazy-loaded. V1/V2 include a synthesized GDDD entry.

ChdResult — verification result (record)

Property Type Description
Error ChdError Result code.
Version uint? CHD version (1–5).
Sha1 byte[]? SHA1 from the header.
Md5 byte[]? MD5 from the header.
IsSuccess bool Error == Chderrnone.
Sha1Hex string Lowercase hex, or "(none)".
Md5Hex string Lowercase hex, or "(none)".

Supports deconstruction: var (err, ver, sha1, md5) = result;


ChdHeaderInfo — full header DTO (record)

Returned by Chd.ReadHeader(...). A snapshot of everything in the CHD header, parsed without opening the file for hunk reads and without keeping a file handle open.

Property Type Description
Length uint On-disk header length (76 / 80 / 120 / 108 / 124 for V1–V5).
Version uint CHD format version (1–5).
Flags uint Raw flags field (V1–V4): bit 0 = has parent, bit 1 = writable. Always 0 for V5.
Compression ChdCodec[] Codec slots (up to 4 for V5; V1–V4 use slot 0). All None = uncompressed V5.
HunkBytes uint Size of one hunk.
TotalHunks uint Total number of hunks.
TotalBytes ulong Decompressed image size.
MetaOffset ulong File offset of the first metadata entry (0 = none).
MapOffset ulong File offset of the block map (V5 only; 0 for V1–V4).
Md5 / ParentMd5 byte[]? MD5 hashes (V1–V3; null for V4/V5).
Sha1 / RawSha1 / ParentSha1 byte[]? SHA1 hashes (V3–V5; null for V1/V2).
UnitBytes uint Unit size. V5: from header; V1–V4: derived from metadata (matches ChdFile.UnitBytes).
UnitCount ulong ceil(TotalBytes / UnitBytes) (0 if UnitBytes is 0).
HasParent bool True if this is a differential child (derived from parent hashes).
ObsoleteCylinders / ObsoleteHeads / ObsoleteSectors / ObsoleteHunksize uint Obsolete V1/V2 hard-disk geometry (0 for V3+).

ChdProgress — long-operation progress (record)

Pass an IProgress<ChdProgress> to Chd.CheckFile, Chd.CheckFileWithParent, ChdFile.ReadAllBytes, ChdFile.EnumerateHunks, or ChdFile.ExtractToDirectory to receive a report after each decompressed hunk. Wrap it in new Progress<ChdProgress>(...) for UI binding or logging.

Property Type Description
CurrentHunk long Hunks processed so far (1-based; equals TotalHunks when done).
TotalHunks long Total hunks in the image.
BytesProcessed long Decompressed bytes processed so far.
TotalBytes long Total decompressed image size.
Elapsed TimeSpan Wall-clock time since the operation started.
Percent double CurrentHunk / TotalHunks × 100 (0–100).
var progress = new Progress<ChdProgress>(p =>
    Console.WriteLine($"{p.Percent:F0}% — {p.BytesProcessed:N0}/{p.TotalBytes:N0} bytes ({p.Elapsed.TotalSeconds:F1}s)"));

var result = Chd.CheckFile(File.OpenRead("game.chd"), "game.chd", deepCheck: true, progress);

For Chd.CheckFile(deepCheck: true), reports arrive in hunk order from the internal hashing thread — an IProgress<T> built with new Progress<ChdProgress>(...) marshals them back to the capturing context automatically. All parameters default to null, so existing callers are unaffected.


Cancellation

Every long-running operation accepts an optional trailing CancellationToken (default default) and throws OperationCanceledException when cancellation is requested: Chd.CheckFile, Chd.CheckFileWithParent, ChdFile.Open/OpenAsync (all overloads), ReadHunk/ReadHunkAsync, Read/ReadAsync, ReadAllBytes, and ExtractToDirectory/ExtractToDirectoryWithReporting. Async twins pass the token to Task.Run too, so a pre-cancelled token yields a cancelled task.

For CheckFile(deepCheck: true) the caller token is linked into the verification pipeline's internal CancellationTokenSource (CreateLinkedTokenSource), so cancellation stops the producer/workers/hasher immediately; the method then throws OperationCanceledException rather than returning a bogus hash-mismatch error over partial data. Cancellation is never swallowed into a ChdError result by extraction — it always propagates as OperationCanceledException.

using var cts = new CancellationTokenSource();
var result = Chd.CheckFile(File.OpenRead("game.chd"), "game.chd", deepCheck: true, cancellationToken: cts.Token);

ChdMetadataEntry — metadata record

public record ChdMetadataEntry(string Tag, byte[] Data)

Member Type Description
Tag string 4-char tag, e.g. "GAME", "DISC", "HARD", "GDDD", "CHT2".
Data byte[] Raw payload bytes (ASCII text or binary).
Flags byte (init) Entry flags from the header (bit 0 = checksummed).
IsText bool True if the data is printable ASCII.
GetText() string ASCII text representation (empty for oversized data).
ToString() string GAME: gauntlet or TAG: N bytes.

Equality is based on Tag + Data only (the Flags byte is excluded).


ChdTrackInfo — CD/GD-ROM track (class)

Property Type Description
TrackNumber int 1-based track number.
TrackType ChdTrackType Mode1, Mode1Raw, Mode2, Mode2Form1, Mode2Form2, Mode2FormMix, Mode2Raw, Audio.
SubType ChdSubType None, Normal, Raw.
DataSize int Bytes per sector (2048, 2352, …).
SubSize int Subcode bytes per sector (0 or 96).
Frames int Frames in the track.
ExtraFrames int Padding frames (4-frame alignment).
PreGap int Pregap frames (index 00 → 01).
PostGap int Postgap frames.
PreGapType / PreGapSubType ChdTrackType / ChdSubType Pregap sector format.
PreGapDataSize / PreGapSubSize int Pregap sector sizes.
PadFrames int GD-ROM pad frames.
StartFrame ulong CHD frame offset where the track starts.
GetTypeString() string e.g. "MODE1/2048", "AUDIO".
GetSubTypeString() string e.g. "RW", "RW_RAW", "NONE".

CdRomAddress — MSF ↔ LBA conversion (static)

CHDSharp.Utils namespace. Pure math, no dependencies. MSF values are BCD-encoded as found in CD sector headers and drive addressing: 0x02 = 2 minutes, 0x10 = 10 minutes. Per the Red Book, LBA 0 corresponds to MSF 00:02:00 (the 2-second lead-in offset); the Alt variants omit that offset for systems (Sega CD, PC Engine) that address frames relative to the start of the disc data.

Member Signature Description
MsfToLba int MsfToLba(byte m, byte s, byte f) BCD MSF → LBA, (m*60 + s)*75 + f - 150. Negative for lead-in positions before 00:02:00.
MsfToLbaAlt int MsfToLbaAlt(byte m, byte s, byte f) BCD MSF → absolute frame count (no -150).
LbaToMsf (byte m, byte s, byte f) LbaToMsf(int lba) LBA → BCD MSF (lba + 150, decompose, pack BCD).
LbaToMsfAlt (byte m, byte s, byte f) LbaToMsfAlt(int lba) Frame count → BCD MSF (no +150).
FramesPerSecond / SecondsPerMinute / PregapFrames const int 75 / 60 / 150.

Throws ArgumentOutOfRangeException when a byte is not valid BCD (a nibble above 9), when the resulting MSF position would be negative, or when the minute field would exceed 99 (the BCD limit).

using CHDSharp.Utils;

int lba = CdRomAddress.MsfToLba(0x00, 0x02, 0x00);      // 0
var (m, s, f) = CdRomAddress.LbaToMsf(8850);            // (0x02, 0x00, 0x00)
var (altM, altS, altF) = CdRomAddress.LbaToMsfAlt(150); // (0x00, 0x02, 0x00)

ExtractResult / TrackExtractResult

ExtractResult (record): CreatedFiles (IReadOnlyList<string>), TrackResults (IReadOnlyList<TrackExtractResult>), Error (ChdError), IsCompleteSuccess, HasTrackFailures.

TrackExtractResult (record): TrackNumber, FilePath (string?), Error, IsSuccess.


Enums

ChdCodec — 4-char codec tags

None = 0, Zlib (zlib), Lzma (lzma), Huffman (huff), Flac (flac), Zstd (zstd), Cdzlib (cdzl), Cdlzma (cdlz), Cdflac (cdfl), Cdzstd (cdzs), Avhuff (avhu), Error.

ChdTrackType

Mode1 = 0, Mode1Raw = 1, Mode2 = 2, Mode2Form1 = 3, Mode2Form2 = 4, Mode2FormMix = 5, Mode2Raw = 6, Audio = 7.

ChdSubType

None = 0, Normal = 1, Raw = 2.

CompressionType — per-hunk map entry types

Compressiontype0..3 (codec slots), Compressionnone, Compressionself, Compressionparent, Compressionrlesmall, Compressionrlelarge, Compressionself0/1, Compressionparentself, Compressionparent0/1, Compressionmini, Compressionerror, Compressionzero, Compressiontype2Nd.

ChdError

The complete 29-value error enum — see Error Codes. Every value has a human-readable message via the GetMessage() extension:

ChdError err = ChdFile.Open("missing.chd", out _);
Console.WriteLine(err.GetMessage());   // "File not found"

Extension methods

ChdErrorExtensions.GetMessage(this ChdError) — human-readable error text. ChdSharp also exposes big-endian helpers (BigEndian/EndianHelpers) internally for the test suite.

Clone this wiki locally