Documentation
¶
Overview ¶
Package chd provides parsing for CHD (Compressed Hunks of Data) disc images. CHD is MAME's compressed disc image format, widely used by RetroArch and other emulators.
Package chd provides parsing for CHD (Compressed Hunks of Data) disc images.
Index ¶
- Constants
- Variables
- func IsCDCodec(tag uint32) bool
- func RegisterCodec(tag uint32, factory func() Codec)
- type CDCodec
- type CHD
- func (c *CHD) Close() error
- func (c *CHD) DataTrackSectorReader() io.ReaderAt
- func (c *CHD) DataTrackSize() int64
- func (c *CHD) FirstDataTrackOffset() int64
- func (c *CHD) Header() *Header
- func (c *CHD) RawSectorReader() io.ReaderAt
- func (c *CHD) SectorReader() io.ReaderAt
- func (c *CHD) Size() int64
- func (c *CHD) Tracks() []Track
- type Codec
- type Header
- type HunkMap
- type HunkMapEntry
- type Track
Constants ¶
const ( // CodecNone indicates uncompressed data. CodecNone uint32 = 0x00000000 // CodecZlib is the standard zlib codec ("zlib"). CodecZlib uint32 = 0x7a6c6962 // CodecLZMA is the LZMA codec ("lzma"). CodecLZMA uint32 = 0x6c7a6d61 // CodecHuff is the CHD Huffman codec ("huff"). CodecHuff uint32 = 0x68756666 // CodecFLAC is the FLAC audio codec ("flac"). CodecFLAC uint32 = 0x666c6163 // CodecZstd is the Zstandard codec ("zstd"). CodecZstd uint32 = 0x7a737464 // CodecCDZlib is the CD zlib codec ("cdzl"). // Compresses CD data sectors with zlib, subchannel with zlib. CodecCDZlib uint32 = 0x63647a6c // CodecCDLZMA is the CD LZMA codec ("cdlz"). // Compresses CD data sectors with LZMA, subchannel with zlib. CodecCDLZMA uint32 = 0x63646c7a // CodecCDFLAC is the CD FLAC codec ("cdfl"). // Compresses CD audio sectors with FLAC, subchannel with zlib. CodecCDFLAC uint32 = 0x6364666c // CodecCDZstd is the CD Zstandard codec ("cdzs"). // Compresses CD data sectors with Zstandard, subchannel with zlib. CodecCDZstd uint32 = 0x63647a73 )
Codec tag constants (as 4-byte big-endian integers representing ASCII strings). CD-ROM specific codecs handle both data and subchannel compression.
const ( // MaxCompMapLen is the maximum compressed map size (100MB). MaxCompMapLen = 100 * 1024 * 1024 // MaxNumHunks is the maximum number of hunks (10M = ~200GB uncompressed). MaxNumHunks = 10_000_000 // MaxMetadataLen is the maximum metadata entry size (16MB, matches 24-bit limit). MaxMetadataLen = 16 * 1024 * 1024 // MaxNumTracks is the maximum number of tracks (200, generous for any disc). MaxNumTracks = 200 // MaxMetadataEntries is the maximum metadata chain entries (prevents loops). MaxMetadataEntries = 1000 )
Allocation limits to prevent DoS from malicious CHD files.
const ( HunkCompTypeCodec0 = 0 // Compressed with compressor 0 HunkCompTypeCodec1 = 1 // Compressed with compressor 1 HunkCompTypeCodec2 = 2 // Compressed with compressor 2 HunkCompTypeCodec3 = 3 // Compressed with compressor 3 HunkCompTypeNone = 4 // Uncompressed HunkCompTypeSelf = 5 // Reference to another hunk in this CHD HunkCompTypeParent = 6 // Reference to parent CHD HunkCompTypeRLESmall = 7 // RLE: repeat last compression type (small count) HunkCompTypeRLELarge = 8 // RLE: repeat last compression type (large count) HunkCompTypeSelf0 = 9 // Self reference to same hunk as last HunkCompTypeSelf1 = 10 // Self reference to last+1 HunkCompTypeParSelf = 11 // Parent reference to self HunkCompTypePar0 = 12 // Parent reference same as last HunkCompTypePar1 = 13 // Parent reference last+1 )
Hunk compression types (V5 map entry types).
const ( // MetaTagCHT2 is the CD Track v2 metadata tag ("CHT2") MetaTagCHT2 = 0x43485432 // MetaTagCHCD is the CD metadata tag ("CHCD") MetaTagCHCD = 0x43484344 // MetaTagCHTR is the CD Track v1 metadata tag ("CHTR") MetaTagCHTR = 0x43485452 // MetaTagGDTR is the GD-ROM track metadata tag ("CHGD") MetaTagGDTR = 0x43484744 )
Metadata tag constants (as 4-byte big-endian integers)
Variables ¶
var ( // ErrInvalidMagic indicates the file does not have a valid CHD magic word. ErrInvalidMagic = errors.New("invalid CHD magic: expected MComprHD") // ErrInvalidHeader indicates the header structure is invalid. ErrInvalidHeader = errors.New("invalid CHD header") // ErrUnsupportedVersion indicates an unsupported CHD version. ErrUnsupportedVersion = errors.New("unsupported CHD version") // ErrUnsupportedCodec indicates an unsupported compression codec. ErrUnsupportedCodec = errors.New("unsupported compression codec") // ErrInvalidHunk indicates an invalid hunk index. ErrInvalidHunk = errors.New("invalid hunk index") // ErrDecompressFailed indicates decompression failed. ErrDecompressFailed = errors.New("decompression failed") // ErrCorruptData indicates data corruption was detected. ErrCorruptData = errors.New("data corruption detected") // ErrNoTracks indicates no track metadata was found. ErrNoTracks = errors.New("no track metadata found") // ErrInvalidMetadata indicates invalid metadata format. ErrInvalidMetadata = errors.New("invalid metadata format") )
Common errors for CHD parsing.
Functions ¶
func RegisterCodec ¶
RegisterCodec registers a codec factory for the given tag.
Types ¶
type CDCodec ¶
type CDCodec interface {
Codec
// DecompressCD decompresses CD-ROM data with sector/subchannel handling.
// hunkBytes is the total size of a decompressed hunk.
// frames is the number of CD frames (sectors) in the hunk.
DecompressCD(dst, src []byte, hunkBytes, frames int) (int, error)
}
CDCodec decompresses CD-ROM specific hunk data. CD codecs handle the separation of sector data and subchannel data.
type CHD ¶
type CHD struct {
// contains filtered or unexported fields
}
CHD represents a CHD (Compressed Hunks of Data) disc image.
func (*CHD) DataTrackSectorReader ¶
DataTrackSectorReader returns an io.ReaderAt for the first data track, providing 2048-byte logical sectors. This is essential for discs like Neo Geo CD that have audio tracks before the data track.
func (*CHD) DataTrackSize ¶
DataTrackSize returns the logical size of the first data track in bytes. For ISO9660 parsing, this is the size in 2048-byte sectors.
func (*CHD) FirstDataTrackOffset ¶
FirstDataTrackOffset returns the byte offset to the first data track. This is useful for reading disc headers for Sega Saturn/CD identification.
func (*CHD) RawSectorReader ¶
RawSectorReader returns an io.ReaderAt that provides access to raw 2352-byte sectors. This is useful for reading disc headers that may be at the start of raw sector data.
func (*CHD) SectorReader ¶
SectorReader returns an io.ReaderAt that provides access to decompressed sector data with 2048-byte logical sectors (Mode1/Mode2 data portion only). This is suitable for ISO9660 filesystem parsing. Note: For multi-track CDs with audio tracks first, use DataTrackSectorReader() instead.
type Codec ¶
type Codec interface {
// Decompress decompresses src into dst.
// dst must be pre-allocated to the expected decompressed size.
// Returns the number of bytes written to dst.
Decompress(dst, src []byte) (int, error)
}
Codec decompresses CHD hunk data.
type Header ¶
type Header struct {
Magic [8]byte // "MComprHD"
HeaderSize uint32 // Header length in bytes
Version uint32 // CHD version (3, 4, or 5)
Compressors [4]uint32 // Compression codec tags (V5)
LogicalBytes uint64 // Total uncompressed size
MapOffset uint64 // Offset to hunk map
MetaOffset uint64 // Offset to metadata
HunkBytes uint32 // Bytes per hunk
UnitBytes uint32 // Bytes per unit (sector size)
RawSHA1 [20]byte // SHA1 of raw data
SHA1 [20]byte // SHA1 of raw + metadata
ParentSHA1 [20]byte // Parent SHA1 (for delta CHDs)
// V3/V4 specific fields
Flags uint32 // V3/V4 flags
Compression uint32 // V3/V4 compression type
TotalHunks uint32 // V3/V4 total number of hunks
}
Header represents a CHD file header. This struct supports V5 format (current standard) with fields for earlier versions.
func (*Header) IsCompressed ¶
IsCompressed returns true if the CHD uses compression.
type HunkMap ¶
type HunkMap struct {
// contains filtered or unexported fields
}
HunkMap manages the hunk map and caching for a CHD file.
func NewHunkMap ¶
NewHunkMap creates a new hunk map from the CHD header and reader.
type HunkMapEntry ¶
HunkMapEntry represents a single entry in the V5 hunk map.
type Track ¶
type Track struct {
Type string
SubType string
Number int
Frames int
Pregap int
Postgap int
DataSize int
SubSize int
StartFrame int
}
Track represents a CD track in the CHD file.
func (*Track) IsDataTrack ¶
IsDataTrack returns true if this is a data track (not audio).
func (*Track) SectorSize ¶
SectorSize returns the total size of each sector including subchannel data.