Error Code Modeler - Lossless compression for CD image files
ECM reduces the size of CD image files (BIN, CDI, NRG, CCD, and other raw sector formats) by eliminating redundant Error Correction/Detection Codes (ECC/EDC) from each sector.
The encoder automatically detects sector types and strips predictable data. The decoder regenerates full 2352-byte raw sectors. Compression is completely lossless.
Note: "Cooked" ISO files (2048 bytes/sector) contain no ECC/EDC data and will see no size reduction.
- Lossless - Bit-perfect roundtrip compression/decompression
- Automatic detection - Identifies Mode 1, Mode 2 Form 1/2 sectors
- Streaming support - Works with stdin/stdout for pipeline integration
- CUE generation - Optional CUE sheet creation on decode
- Cross-platform - Linux, macOS, Windows
# Configure and build
meson setup build
meson compile -C build
# Run tests
meson test -C build
# Install (optional)
sudo meson install -C buildOr using the just command runner:
just build # Build release
just rebuild # Clean and rebuild
just test # Run tests
just benchmark # Run performance benchmarksbrew install --cask ecmCompress a CD image by stripping ECC/EDC data:
ecm game.bin # Creates game.bin.ecm
ecm game.bin compressed.ecm # Custom output name
cat game.bin | ecm - - > out.ecm # Streaming modeFull syntax:
ecm [-v|--verbose] <input> [output]| Option | Description |
|---|---|
-v, --verbose |
Show sector processing details |
input |
CD image file (BIN, CDI, NRG, CCD, etc.) or - for stdin |
output |
ECM file (defaults to <input>.ecm) or - for stdout |
Restore the original CD image:
unecm game.bin.ecm # Creates game.bin
unecm --cue game.bin.ecm # Also creates game.bin.cue
unecm game.bin.ecm restored.bin # Custom output nameFull syntax:
unecm [-v|--verbose] [--cue] <input.ecm> [output]| Option | Description |
|---|---|
-v, --verbose |
Show record decoding details |
--cue |
Generate a CUE sheet file |
input.ecm |
ECM file (must end in .ecm) or - for stdin |
output |
Output file (defaults to input without .ecm) or - for stdout |
CD-ROM sectors contain user data plus error correction codes. ECM identifies sector types and strips the predictable portions:
| Sector Type | Raw Size | Stored | Savings | Description |
|---|---|---|---|---|
| Mode 1 | 2352 B | 2051 B | ~13% | Standard data with full ECC/EDC |
| Mode 2 Form 1 | 2352 B | 2052 B | ~13% | XA data with ECC/EDC |
| Mode 2 Form 2 | 2352 B | 2336 B | ~1% | XA audio/video (EDC only) |
| Literal | varies | varies | 0% | Non-standard data (stored as-is) |
Typical compression ratios for game discs: 10-15% size reduction.
ECM automatically selects the optimal mode based on input type:
| Mode | Input Type | Buffer | Best For |
|---|---|---|---|
| Batch | Regular files | ~1 MB | Large files, best compression |
| Streaming | stdin/pipes | ~2.4 KB | Pipelines, memory-constrained |
Batch mode groups consecutive same-type sectors for better compression ratios. Use regular files when possible for best results.
See FORMAT.md for the ECM file format specification.
Run benchmarks with:
just benchmarkExample results (Apple M1):
EDC Computation: ~370 MB/s
ECC Generation: ~220,000 sectors/sec
Sector Detection: ~104,000 sectors/sec
Encode Throughput: ~120 MB/s
Decode Throughput: ~120 MB/s
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Ensure tests pass (
meson test -C build) - Ensure code is formatted (
just fmt) - Submit a pull request
This project is licensed under the GNU General Public License v2.0 - see the LICENSE file for details.
- Aleksandr Pavlov ckidoz@gmail.com
See AUTHORS.md for full attribution.