Repository navigation
Releases: purelogiccode/CHDSharp
Release list
CHDSharp v1.5.2
CHDSharp v1.5.2 - What's New
Released: 2026-10-21 - Full changelog - NuGet
CHDSharp v1.5.2 rolls up the v1.5.1 cue-layout parity fixes and adds a repo-wide code-quality pass plus fully automated wiki and
documentation-site deployment.
Download (CLI)
| Platform | Bundle |
|---|---|
| Windows x64 | CHDSharp_win-x64_v1.5.2.zip |
| Windows ARM64 | CHDSharp_win-arm64_v1.5.2.zip |
| Linux x64 | CHDSharp_linux-x64_v1.5.2.zip |
| Linux ARM64 | CHDSharp_linux-arm64_v1.5.2.zip |
| macOS Intel | CHDSharp_osx-x64_v1.5.2.zip |
| macOS Apple Silicon | CHDSharp_osx-arm64_v1.5.2.zip |
Every bundle contains a framework-dependent single-file CHDSharp / CHDSharp.exe
build (the .NET runtime is not embedded) plus LICENSE.txt, README.md, README.txt
and this document. The .NET 10 runtime
is required.
Fixed: REM LEAD-OUT at or before the session's last track
The parser compared the track's frame count with leadOut - index00 using two int values.
MAME compares a uint32_t frame count against a signed int32_t end frame
(cdrom.cpp:2748), so a negative end frame converts to a huge unsigned value and the trim is
skipped. Cues that declare REM LEAD-OUT 00:00:00 (or any address at or before the last track
of the session) therefore failed with:
Track 2: the session lead-out values leave a negative length (-11400 frames); the cue's
REM SESSION/LEAD-OUT values do not match the image.
while chdman createcd encoded the same cue, because the no-op lead-out leaves the cue's INDEX
positions in charge of the layout. The parser now performs the same unsigned comparison, so the
track layout and the CHD bytes match chdman.
Fixed: a pad larger than its track zeroed the whole track
The CD reader treated the last PadFrames frames of a track as zero-filled padding. In chdman
the pad start is an unsigned offset from the track start (chdman.cpp:471-472); when the pad is
larger than the track the offset wraps below the track start, the pad region is unreachable, and
every frame is read from the source file. The encoder now mirrors that rule, and the GD-ROM
data/pad/split ordering follows the same frame layout (splitStart = frames - splitFrames,
padStart = splitStart - padFrames).
Code quality (new in v1.5.2)
The whole solution is now clean under the ReSharper command-line inspector:
jb inspectcode CSharp_CHDSharp.sln --severity=WARNING reports zero warnings or errors
(308 before the cleanup). The policy lives in the root .editorconfig:
- Vendored codecs are exempt and untouched.
VendoredZLib,VendoredLZMA,VendoredFlac
andVendoredZSTDare third-party ports; byte-for-bytechdmanparity depends on them staying
verbatim, so their style/quality inspections are disabled instead of "fixed". - Consumer-facing models are exempt from "never used" inspections - public library records,
the JSON corpus manifest, and the WPF data models are read by callers, serializers and XAML
bindings rather than by the declaring assembly. - First-party findings were fixed: redundant null checks in the CLI encode paths, a write-only
AVI stream field, and dead tester state (LogEntry/LogEntriesand the unread
PerFileResult.FilePath).
CI, wiki & docs (new in v1.5.2)
- Docs deploy from CI. After the three-OS build/test matrix passes on a push to
main, the
CI workflow regenerates the GitHub wiki fromdocs/and requests a Pages rebuild. The release
workflow does the same for tags, so the wiki and the documentation site stay in sync with the
code. - Dark theme by default. The documentation site uses a dark palette with a persisted
light/dark toggle andcolor-schememetadata. - Badges everywhere. Every README (root, library, CLI, tests, generator, tester, benchmarks
anddocs/) starts with its CI/NuGet/platform badge row. - Release routine documented.
AGENTS.mdnow records the version bump, verification, tag,
bundle and wiki/Pages steps used for this release.
Verification
- New
chdman createcdbyte-parity fixtures: zero lead-out, lead-out before the track, and the
pad-larger-than-track layout. - Parser regression tests for both lead-out shapes.
CHDSharpEncoderTest454/454,CHDSharpTest4214/4214, battle harness--quick905/905 checks.- Full
dotnet testacrossnet8.0/net9.0/net10.0: 14,004 passed, 0 failed; full battle
harness: 3,174/3,174 checks, byte-identicalchdmanoutput.
Upgrading
No public API changes. Replace the package; cues that encoded before produce the same bytes, and
the two layouts above now encode instead of throwing.
CHDSharp v1.5.0
CHDSharp v1.5.0 — What's New
Released: 2026-10-16 · Full changelog · NuGet
CHDSharp v1.5.0 is the first release produced end-to-end by the GitHub Actions pipeline:
one tag push builds the six platform bundles, creates the GitHub release, publishes the
NuGet package, and updates the wiki and
the documentation site.
Download (CLI)
| Platform | Bundle |
|---|---|
| Windows x64 | CHDSharp_win-x64_v1.5.0.zip |
| Windows ARM64 | CHDSharp_win-arm64_v1.5.0.zip |
| Linux x64 | CHDSharp_linux-x64_v1.5.0.zip |
| Linux ARM64 | CHDSharp_linux-arm64_v1.5.0.zip |
| macOS Intel | CHDSharp_osx-x64_v1.5.0.zip |
| macOS Apple Silicon | CHDSharp_osx-arm64_v1.5.0.zip |
Every bundle contains a framework-dependent single-file CHDSharp / CHDSharp.exe
build (the .NET runtime is not embedded) plus LICENSE.txt, README.md, README.txt
and this document. The .NET 10 runtime
is required. On Linux/macOS run chmod +x CHDSharp if the binary is not executable after
unzipping.
Fixed: built-in update check
The CLI's "a new version is available" notice now links directly to the download for
your platform. The bundle the release ships (CHDSharp_<os>-<arch>_v<version>.zip) is
exactly the name the update check looks up; previously it searched for the wrong asset
name built from the currently running version, so the direct link never resolved and
users were sent to the releases page instead.
Release engineering
- One tag, one release —
Releaseworkflow: bundles (win/linux/osx × x64/arm64),
GitHub release, NuGet push, wiki sync, Pages rebuild. The workflow refuses to run if
the tag does not matchDirectory.Build.props. - NuGet publishing is idempotent — re-running the workflow skips a version that is
already on nuget.org. - GitHub releases now ship only the CLI — the WPF Tester remains source-only.
Also in this release
- Wiki + documentation site in sync — the
docs/folder is deployed twice from CI:
as the documentation site and as the
GitHub wiki, both with the same side menu. - Dark theme by default on the documentation site (with a persisted light/dark toggle).
- Test harness hardening — test-spawned CLI runs set
CHDSHARP_NO_BUG_REPORTS=1/
CHDSHARP_NO_TELEMETRY=1, so local full-suite runs no longer file bug reports. - Badges on every README (CI, release, NuGet, platform, parity, license).
Upgrading from v1.4.3 (or earlier)
v1.5.0 rolls up everything from v1.4.4 and v1.4.5:
- Multisession cue parity — ports MAME's
REM SESSION/REM LEAD-IN/REM LEAD-OUT
/ session-pregap layout rules (IsoBuster/ImgBurn single-bin trim with zero-filled
inter-session gaps, Redump/DiscImageCreator synthesized lead-in/out,.imgheuristic).
Multisession cues now encode byte-identically tochdman createcd. - Redump multi-cue Dreamcast GD-ROM parity — cues with
REM SINGLE-DENSITY AREA/
REM HIGH-DENSITY AREAmarkers get the fullis_gdicuelayout (split pregap regions,
LBA-45000 padding,CHGDmetadata); verified byte-identical on a real 1.19 GB Redump
multi-cue with a byte-perfectchdman extractcdround-trip. - cdrdao TOC
STARTparity — a bareSTARTline (cdrdao's documented form) is
accepted as "no pregap", matching MAME 0.289'sparse_tocexactly.
NuGet
dotnet add package CHDSharp --version 1.5.0Targets net8.0, net9.0 and net10.0 — pure C#, zero native dependencies. Every
codec (zlib, lzma, huffman, flac, zstd, AVHuff and the CD variants) is implemented
in-repo and ships inside the package.
v1.4.3
CHDSharp v1.4.3
Consolidates all changes since v1.4.2. Closes the partial-tail raw-encode corruption and the last FLAC byte-parity divergence. Battle harness green: 3174/3174 synthetic vs MAME 0.289.
Partial-tail raw-encode corruption fix
EncodeRaw/createraw on inputs of ≥ 513 hunks whose length is not a hunk multiple could produce a self-consistent-but-wrong CHD: stale compression ring-buffer slots from the previous fill cycle leaked into partial final hunks. The fix landed alongside guardrail tests so the class of bug cannot silently return:
- a synthetic partial-tail probe that pins the exact stale-slot bytes,
- partial-last-hunk unit tests per codec,
- a resized long-tail case in the battle harness (
raw-encode long-tail x flac/zlib/zstd).
FLAC encoder byte parity
The vendored FLAC encoder now matches chdman byte-for-byte on the remaining divergence: the fixed-predictor analysis window and the tukey window's cosf rounding (native cosf semantics replicated). Verified byte-identical on:
- the 7.8 GB Perfect Dark Zero XGD2 image (1,912,816 hunks, chdman default codec list),
- a 100 MB partial-tail slice of the same source,
- three single-hunk repro cases.
Byte-parity fixes earlier in the cycle
- Stale work-buffer tail + LZMA match-finder insert parity (raw encode).
Diagnostics and output
- Detailed decompression-failure messages: hunk index, codec, CRC/truncation reasons.
- chdman-style progress + speed-meter output.
Verification status
CHDSharpTest: 12,648/12,648 (436/436 per TFM on net8.0/net9.0/net10.0 → 1,308/1,308 aggregate via the console runners).CHDSharpEncoderTest: 1,308/1,308.CHDSharpBattleTest: 3174/3174, includingraw-encode long-tail x *for all three codecs.
NuGet Package
dotnet add package CHDSharp --version 1.4.3
Targets net8.0, net9.0, net10.0. Pure C# - zero native dependencies.
Full Changelog: v1.4.2...v1.4.3
v1.4.2
What's New in CHDSharp
Final chdman parity gaps closed — battle 2907/2907
- LZMA byte-parity hash-update-order bug fixed (
c470879): raw encoding now replicateschd.cpp's 256-hunk compression work buffer (RingBufferedRawReader) — ring slots past EOF keep stale bytes from the previous 128-hunk batch and the raw SHA-1 folds only valid bytes, exactly likem_compsha1.append(dest, numbytes). Also touchesFlacLpcMath,LzmaEncoderand the FLAC encoder for byte-exact output. createhdsize / CHS quirks (e4f3735): size parsing now matcheschdman.cpp:2035(sscanf("%I64u")reads leading digits only, so"512K"= 512 bytes) and small sizes are rounded up to the guessed CHS product (guess_chsparity), including theIDENT/GDDDwide-CHS case.- Laserdisc AVI byte-parity (
e4f3735):AviWriteroutput is now byte-identical tochdman createld/extractld. - Strict
info/verifyoptions (e4f3735): full-argument option validation (duplicate-i/--inputdetection, per-command option sets),inforeturns exit code 1 on failure,verifyparity withchdman'sreport_errorhandling. - DVD metadata empty payload (
c470879):DVD_METADATA_TAGwritten with zero-length payload perchdman. - CLI exit codes (
c470879): failure paths now returnchdman-consistent non-zero exit codes. - Test fixes in
CHDSharpEncoderTest/CHDSharpTestaccompany the parity work. Missmatch.mdreplaces the deleteddivergency.mdand records the battle result: 2907 checks — 2907 passed, 0 failed against MAME 0.289.
CLI improvements
createrawnow also accepts--hunk-size/--unit-sizealiases alongside--hunksize/--unitsize/-hs/-us(ea375e1).extractcdfilename template%tregex fixed (named capture groups; escaped%%handling) (ea375e1).hashcommand help corrected:--result text|json|sfvand--tracksflags (ea375e1).createhdgeometry override viaLogicalLengthBytesfor byte-parity encoding of over-/under-sized sources (c470879).
Build & tests
CHDSharpBattleTestmulti-targetsnet8.0;net9.0;net10.0withLangVersion=latestand copies the built CLI into its output for self-contained battle runs (e4f3735).- Analyzer warnings silenced (MA0008 StructLayout, unused-variable suppressions) (
aaad13d). - Formatting and style pass across CLI, encoder, and vendored codecs (
2e3a1e9,b858192).
Documentation
- New CLI command reference:
docs/cli-commands.md(413 lines) plus expandedCHDSharpCli/README.md— fullchdman/CHDSharp argument tables for every command (2bef641e). - CHD format history added to
docs/chd-format.md; language simplified and stale DVD metadata notes corrected (d208521). - Wiki home page (
docs/README.md) rewritten with CHD history;ReleaseNotesadded to sidebar and_config.yml(ff51e98). - Docs site URL fixed to the GitHub repository (
3dedc71). - Peterson Fernandes added to key contributors across all docs (
dfb74b7).
v1.4.1
CHDSharp v1.4.1
What's New
GD-ROM support is now complete
extractcdcorrectly handles Dreamcast GD-ROM Redump images (REM SINGLE-DENSITY / HIGH-DENSITY, 45000-frame boundary,has_physical_pregapfixup). Works for both GDI and CUE/BIN.- Per-track extraction now uses the correct mode automatically (
GDIvsCUEBINvsTOC).
Smarter copy and parent handling
copynow picks the right default codecs for each image type automatically (HD/DVD →lzma,zlib,huff,flac/ CD/GD →cdlz,cdzl,cdfl/ laserdisc →avhu), same aschdman.- Parent CHDs: hunk size is inherited from the parent when omitted, and mismatched sizes are rejected as expected.
Fixed
Hard disks (createhd / createraw)
createhd -i image.imgnow writesGDDDgeometry metadata — output is now byte-identical tochdman(was 51 bytes short).createhd --identnow correctly reads CHS from the ATA IDENTIFY data.- Blank hard disks now correctly require
-c none(was silently accepting compressed codecs). createhdnow validates interactions between-tp,-chsand-size/ parent images.createrawnow correctly requires--unitsizewhen no parent is given and validates hunk size (16 B – 1 MiB, multiple of unit size).listtemplatesnow shows all 17 templates (was missing 4 Quantum Fireball drives).
CD / GD-ROM extraction (extractcd)
extractcdnow defaults to cooked sectors (2048/2352 bytes, no subcode, audio byte-swapped) — now matcheschdman extractcdfor all 43 CDs + 3 GD-ROMs. Use--rawto keep 2448-byte raw frames.- Library
ExtractToDirectory(..., cooked: true)does the same — the defaultcooked: falseis kept for backward compatibility. - Large extractions now use a 32 MiB aligned buffer and correct audio byte-swap (CUEBIN always, GDI only for CHD v5+).
DVD
createdvd/BuildDvdMetadatanow writes an emptyDVDtag (length 0) instead of a0x00byte — matcheschdman.
Metadata
addmeta --valuetextno longer adds a trailing NUL (wastext+'\0', nowtext).
CLI — stricter, now matches chdman
- Unknown options, duplicate options and missing values now error correctly.
- Each command now only accepts its valid options (e.g.
createrawrejects-tp). -isb/-ish/-ib/-ihslicing now correctly rejects mixing bytes and hunks.10MBwith trailingBis now handled, and--sizeplain numbers are strict.
Diagnostics
info --verboseandverify --verbosenow show per-codec hunk stats (SELF/PARENT/MINIbuckets).- Progress now throttles to 0.5 s and errors go to
stderrasError: ....
Docs / Code quality
createcd -c cdzlon audio CDs is now documented: container bytes may differ due to FLAC subframe choice, but SHA-1 /verifyare identical.- Zero build warnings. Added
Meziantou.Analyzerto all projects.
Upgrade Notes
- No API break. Library code keeps compiling.
- CLI is now stricter. Scripts that passed invalid combos before (e.g.
createhdblank with-c zlib,extractcd -tp 1,--splitbinwithout%t) will now fail — same aschdman. Fix the flags. - Cooked vs raw: If you compared
ExtractToDirectoryoutput tochdman extractcd, passcooked: true.
Full Changelog: v1.4.0...v1.4.1
v1.4.0
What's New in CHDSharp v1.4.0
Release date: August 26, 2026
This release is the biggest correctness milestone for CHDSharp: the CLI now has full chdman argument parity, the encoder is byte-for-byte identical to MAME for every codec, and a dedicated battle-test harness keeps 2611/2611 synthetic + 3003/3003 real-world parity checks passing against chdman.exe.
Headline: full chdman parity
1. Full chdman CLI argument parity
The CLI (binary renamed from CHDSharpCli to CHDSharp) now accepts every chdman subcommand with matching option names and exit-code conventions:
info verify createraw createhd createcd
createdvd createld extractraw extracthd extractcd
extractdvd extractld copy addmeta delmeta
dumpmeta listtemplates
Common options mirror chdman exactly: --input/-i, --output/-o, --inputparent/-ip, --outputparent/-op, --compression/-c, --hunksize/-hs, --unitsize/-us, --numprocessors/-np, --force/-f, --verbose/-v, --chs, --sectorsize/-ss, and more.
The convenience commands from earlier versions remain available: directory scan, --list, --random, --parent, --toc, --cue, --classify, --detect, --hash, and --batch.
# chdman-style
CHDSharp info -i game.chd
CHDSharp verify -i game.chd
CHDSharp createcd -o game.chd -i game.cue
CHDSharp extractraw -o game.bin -i game.chd
CHDSharp copy -o new.chd -i old.chd -c zstd
CHDSharp addmeta -i game.chd -t GAME -vt "gauntlet"
# convenience extensions
CHDSharp D:\CHD
CHDSharp --random game.chd
CHDSharp --classify game.chd2. Byte-for-byte parity with chdman for all codecs
Every encoder output now matches MAME's chdman byte-for-byte. This closes the three previously non-exact paths:
createld(laserdisc AVHuff) — fixed an off-by-four AVIidx1base offset that shifted audio by one sample and misaligned video; the AVHuff codec now correctly compresses zero-padded single-frame hunks; and the mono-FLAC encoder now evaluates every fixed-predictor order per frame (matching libFLAC 1.4.3 for the mono/48 kHz avhu path).cdzs(CD Zstandard) — the in-repoVendoredZSTDport now emits frames byte-identical to C zstd for the same hunk buffers.zstd(raw Zstandard) — same fix;createraw -c zstdoutput is now byte-identical tochdman.
3. Full chdman battle-test parity — 2611/2611 synthetic + 3003/3003 real-world
The new CHDSharpBattleTest harness exhaustively cross-checks the CHDSharpLib decoder and the CHDSharp.Encoder encoder against chdman.exe:
chdman create*parity (ours and reference bothverifyclean)- byte-identical encode for every writable codec
- decode, extract, and
infoparity - delta/parent, CD, and A/V laserdisc scenarios
It runs on a deterministic corpus (seed 1337) and can also scan real-world CHD folders:
dotnet run --project CHDSharpBattleTest # 2611/2611
dotnet run --project CHDSharpBattleTest -- --quick # smoke run
dotnet run --project CHDSharpBattleTest -- --real "D:\CHD" # real collectionZero external dependencies
The ZstdSharp.Port NuGet package has been replaced by the in-repo VendoredZSTD project — the ZstdSharp 0.7.6 source tree, a full C-to-C# port of the zstd 1.5.5 source (the same version MAME bundles), including both the encoder and the decoder.
The library now has zero external runtime NuGet dependencies. Every codec (zlib, lzma, huffman, flac, zstd, AVHuff, and all CD variants) is vendored in-repo in pure C#.
38 bugs fixed from a deep code review
A code review across the CLI, library, and battle harness resolved 38 issues. Highlights:
- Exit codes & error handling — proper CLI exit codes (
0/1/3),CheckFile(Stream)catchesIOException,VerifyListlogs exception types verbatim. - Encoding —
createcddefaults tocdlz,cdzl,cdfl;createhd --inputroutes toEncodeRaw;verify --inputparentis passed toCheckFileWithParent; all create/copy commands require--forceto overwrite;extractcd --splitbinand GD-ROM.gdiupdates;LzmaStream.Seekreturns the correct position. - Concurrency — thread-safe parallel-verification master error (
StrongBox+Interlocked),DisposeAsyncdrains per-thread codec states, read-ahead no longer over-releases its semaphore. - Robustness —
ReadHunk(Span)caches hunks on success,FindRepeatedBlocksvalidates map offset bounds,ValidateSizeLimitsrejectsUnitbytes == 0,MemoryMappedFiledisposed on view failure,extractrawwrites to a temp file first. - Diagnostics —
Interlockedprogress callbacks, version display usesBuild, bug reports scrub PII, API keys no longer stored in plain text. - CLI helpers —
--batchextension filtering, exact.chdextension checks, symlink skipping, completehelpcoverage,addmetarejects non-ASCII tags.
Plus: flaky-test fixes for .NET 8/9/10, and all compiler/analyzer/Rider warnings resolved across VendoredZSTD and VendoredZLib.
Breaking changes
- CLI binary renamed:
CHDSharpCli.exe→CHDSharp.exe. The subcommand syntax changed to thechdmanstyle (CHDSharp createcd -o out.chd -i in.cue); the old--create/--createcd/--createhd/--copyforms are gone. ZstdSharp.Portpackage removed: replaced by the in-repoVendoredZSTD. Direct consumers of that package should switch to the library's own codecs.
Quick install
dotnet add package CHDSharp --version 1.4.0Targets net8.0, net9.0, and net10.0. Zero native dependencies — runs on Windows, Linux, and macOS.
Full changelog: docs/ReleaseNotes.md
Full Changelog: v1.2.0...v1.4.0
v1.2.0
What's New — CHDSharp v1.2.0
Highlights
- CD/GD-ROM track (TOC) parsing — Full track layout and sector type information from CHD metadata
- Internal build consolidation — Centralized versioning and build properties via
Directory.Build.props - Reproducible builds — Deterministic compilation and embedded SourceLink for debuggable NuGet packages
New Features
CD-ROM & GD-ROM Track Info
New ChdTrackInfo model and ChdTocParser parse the table of contents (TOC) embedded in CHD metadata, providing per-track details:
- Track number, type (Mode1, Mode2, Audio, etc.)
- Sector data size and subcode size
- Pregap, postgap, and padding frame counts
- GD-ROM support (
CHGD/CHGTmetadata tags) - Start frame offset for locating track data
Supports all metadata tag formats: CHTR/CHT2 (text key-value), CHCD (binary), and CHGD/CHGT (GD-ROM).
var tracks = chd.GetTrackInfo();
foreach (var track in tracks)
{
Console.WriteLine($"{track.TrackNumber}: {track.GetTypeString()} " +
$"{track.Frames} frames, pregap={track.PreGap}");
}Improved UnitBytes Calculation
UnitBytes property on ChdFile now derives sector size from metadata for all CHD versions:
- V5 — Reads from header
- V1–V4 — Detects HDD (512B), CD (2448B), or defaults to hunk size
New Enums
ChdTrackType— Matches MAMEcdrom.htrack types (Mode1, Mode1Raw, Mode2, Mode2Form1, Mode2Form2, Mode2FormMix, Mode2Raw, Audio)ChdSubType— Subcode types (None, Normal, Raw)
Package Improvements
- Centralized versioning — All 7 projects share version
1.2.0viaDirectory.Build.props. Bump once and all projects update. - Deterministic builds —
<Deterministic>true</Deterministic>enables byte-for-byte reproducible builds - Improved CI detection —
ContinuousIntegrationBuildnow detects GitHub Actions natively - Updated release notes — Package metadata accurately reflects v1.2.0 features
- Stale artifacts removed — Old build artifacts cleaned from repository
Test Suite
- Track info tests — Validates TOC parsing across all metadata formats and edge cases
- CLI integration tests — End-to-end tests for the command-line tool
- Expanded encoder tests — CRC16, SHA1, and Deflate validation in
CHDSharpEncoderTest
Breaking Changes
None. All public APIs from v1.1.0 remain compatible.
Upgrading
dotnet add package CHDSharp --version 1.2.0Full Changelog: v1.1.0...v1.2.0
v1.1.0
New: UnitBytes property on ChdFile
ChdFile now exposes UnitBytes — the unit size used for parent block address translation.
| Version | Source |
|---|---|
| V5 | Read directly from the CHD header (big-endian uint32 at offset 60) |
| V1-V4 HDD | Derived from GDDD metadata: parses BPS (bytes-per-sector) from the "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d" format |
| V1-V4 CD/GD-ROM | Detects CHCD, CHTR, CHT2, CHGT, CHGD metadata tags → returns 2448 (CD frame size: 2352 data + 96 subcode) |
| V1-V4 fallback | Returns HunkBytes (1:1 mapping) |
The V1-V4 derivation logic mirrors libchdr's header_guess_unitbytes() exactly.
Usage
ChdFile.Open("game.chd", out var chd);
using (chd)
{
Console.WriteLine($"HunkBytes: {chd.HunkBytes}");
Console.WriteLine($"UnitBytes: {chd.UnitBytes}");
// For a CD-ROM CHD: HunkBytes=19584, UnitBytes=2448
// For a hard disk CHD: HunkBytes=4096, UnitBytes=512
// For a raw image CHD: HunkBytes=4096, UnitBytes=4096
}Internal: refactoring
CdFrameSizeconstant visibility changed fromprivatetointernalinCHDReaders.cs(needed byChdFile.GuessUnitBytes())- Pattern matching used for metadata tag checks in
GuessUnitBytes()
Version
All assemblies bumped from 1.0.0 to 1.1.0. NuGet package CHDSharp version updated to 1.1.0.
v1.0.0
Initial release of CHDSharp — a fork of RomVault/CHDSharp by Gordon Jefferyes, heavily extended and modernized.
Available on NuGet:
dotnet add package CHDSharpTargets net8.0, net9.0, and net10.0. Zero native dependencies — every codec is implemented in pure C#.
Highlights
- Zstd codec support (
zstd+cdzs), backed by the managed ZstdSharp.Port - V5 parent/child (differential) CHD chains with wrong-parent detection and
CheckFileWithParent() - Random-access API —
ChdFile.Open(),ReadHunk(),Read()(arbitrary byte ranges across hunk boundaries),ReadAllBytes(),EnumerateHunks() - Async API —
OpenAsync,ReadHunkAsync,ReadAsync,IAsyncDisposable - Metadata support — expose game name, disc labels, and other CHD header metadata
- Comprehensive xUnit test suite with generated test data, cross-checked byte-for-byte against MAME
chdman(info,verify,extractraw) - New
Compressionzerocompression type for unallocated hunks in uncompressed V5 CHDs
New Applications
- CHDSharpCli — verify directories recursively, verify from a path list, random-access self-test, parent/child verification
- CHDSharpTester — WPF UI for batch testing, with progress status bar, About window, and exit confirmation during runs
API Modernization
- Published as a proper NuGet package (
CHDSharp) with SourceLink, symbols package, and package icon - Namespace renamed to
CHDSharp; public API renamed to idiomatic PascalCase (Chd,ChdFile,ChdError,ChdResult, …) - New
TaskCountproperty (1–64, validated) to configure parallel verification threads - New helpers:
IsChdFile(),CheckHeader(),ChdResultwithIsSuccess,Sha1Hex, and friendly error messages - Models and interfaces reorganized into dedicated namespaces; XML documentation added across the public API
Reliability & Hardening
- Buffer bounds, null, and overflow checks across all codecs and readers
ReadByteCheckedthrows on truncated streams instead of silently mis-reading- FLAC
BitReadersafe lookahead fix - Guard against cyclic metadata chains
- Fixed off-by-one, pointer, and null-check bugs in the codec state (
ChdCodecState) - Fixed header version check; added cancellation token and proper task cleanup to the parallel decompression queue
- Fixed compression name display; removed dead code, unused LZMA/FLAC classes, and telemetry
Licensing
- Licensed under MIT
Special Thanks
- Gordon Jefferyes and the RomVault project for the original CHDSharp
- The MAME team for the CHD format and
chdmanreference implementation
Full Changelog: initial release