| title | Embedded Libraries |
|---|---|
| nav_order | 11 |
The solution ships three in-house libraries that replace external tools (maxcso, psxpackager) and add CloneCD support. All three multi-target net10.0;net8.0, are packable, and expose internals to BatchConvertToCHD.Tests via InternalsVisibleTo.
| Library | Purpose | Replaces |
|---|---|---|
| CCDSharp | CloneCD .ccd/.img/.sub parsing + CUE/BIN conversion |
— (new capability) |
| CSOSharp | CSO/CISO decompression (deflate/zlib + LZ4) | maxcso.exe |
| PBPSharp | PlayStation PBP extraction + SFO/TOC parsing | psxpackager.exe |
Purpose: read CloneCD disc-image sets (.ccd descriptor + .img data + optional .sub subchannel) and convert them to CUE/BIN for chdman.
- Main type:
CcdConverter—Parse(inputFile)returns a parsed disc model (DiscImagewithImgFilePath, subchannel info, track table);ConvertToCueBin(inputFile, tempCuePath)writes the CUE/BIN pair. - Integration:
ProcessCcdFileForConversionAsync(MainWindow.xaml.cs:1702) parses the.ccd, converts to CUE/BIN in a temp dir, then converts the cue with chdman. On success the.ccd/.img/.sub/.cdtset is deleted when "delete originals" is enabled. - Archive extractions skip
.imgfiles that belong to a.ccdset to avoid double conversion (MainWindow.xaml.cs:1562–1573). - Failure messages are prefixed
"CCDSharp: Conversion error"and are excluded from bug reports. - Reference sources live under
References/(ccd2cue-master,ccd2iso-main,myccd2cue-main) — third-party material used to build the library, not part of the build. - Testing note: the test project does not reference CCDSharp, so there are currently no CCDSharp unit tests (see Testing).
Purpose: read and decompress CISO (Compressed ISO, .cso) images.
- Main type:
CsoFile—Open(path/stream, out CsoFile)returns aCsoError; exposesUncompressedSize, block metadata,ReadBlock,ExtractToIso(path, progress?, token), and a seekableCsoStreamimplementing the stream contract. - Supports v1 and v2 headers, deflate/zlib and LZ4 compression (
K4os.Compression.LZ4dependency). - Integration:
ArchiveService.ExtractCsoAsync(Services/ArchiveService.cs:52) decompresses to a temp ISO for the conversion pipeline. - Error enum:
CsoError { None, FileNotFound, InvalidHeader, UnsupportedVersion, InvalidBlockSize, ... }. - Tests:
CsoFileTests,CsoStreamTests,CsoHeaderTests, plus byte-for-byte integration tests against real.cso/.isopairs (CsoFileIntegrationTests).
Purpose: parse PlayStation PBP (PSP/PSX eboot) containers and extract PlayStation disc images to CUE/BIN.
- Main type:
PbpFile—Open(path, out PbpFile)/Open(stream, ownsStream, out PbpFile); propertiesHeader,SfoData,Discs(IReadOnlyList<PbpDiscInfo>),IsMultiDisc,Title,DiscId,Category. - Header: magic
0x50425000, 40-byte header with offsets for SFO/ICON0/ICON1/PIC0/PIC1/SND0/DATA.PSP/DATA.PSAR. - Disc detection: PSAR header
PSISOIMG0000→ single disc;PSTITLEIMG000000→ multi-disc (reads 5 position slots); anything else →PbpError.InvalidPsarHeader(the app treats this as "not a PlayStation disc image — PSP application, unsupported variant, or corrupt file" and skips informatively). PbpDiscInfo—ReadBlock,ExtractTo(stream, progress?, token),ExtractToBinCue(binPath, cuePath?, progress?, token); ISO blocks are raw or raw-deflate decompressed; TOC parsed from the PSAR TOC (A0/A1/A2 markers, BCD track numbers). A disc container whose header parsed but that carries no ISO index entries throwsNoIsoIndexException(public, derives fromException) so callers can report the likely cause: a truncated or incomplete download.CueSheetWriter.GenerateCueSheet(binFileName, tocEntries)— emitsFILE ... BINARY,TRACK nn MODE2/2352(data) /AUDIO(audio), withINDEX 00for audio tracks computed as track start minus 150-frame lead-in (clamped ≥ 0).- SFO model:
SfoData(magic0x46535000;GetString/GetUInt32; staticKeyswithBOOTABLE,CATEGORY,DISC_ID,DISC_VERSION,LICENSE,PARENTAL_LEVEL,PSP_SYSTEM_VER,REGION,TITLE),SfoEntry(formats 0x0204 string / 0x0404 uint32),TocEntry,TrackType { Data = 0x41, Audio = 0x01 }. PbpErrorenum:None=0, InvalidHeader=1, FileNotFound=2, IoError=3, CorruptFile=4, InvalidPsarHeader=5, DiscOutOfRange=6, ResourceNotFound=7, DecompressionError=8, TruncatedPsar=9, InvalidSfo=10.TruncatedPsaris returned when the PSAR container parses but no ISO index follows (seeNoIsoIndexException);InvalidSfowhen the PARAM.SFO region lacks the\0PSFsignature. The app maps these to targeted guidance ("most likely truncated or incomplete — re-download") instead of a generic corrupt-file message.- Integration:
ExtractPbpToCueBinAsync(MainWindow.xaml.cs:2918) — multi-disc PBPs produce"{name} - Disc N.bin/.cue"sets; the result (PbpExtractionResult) carriesErrorCode+ a human-readableErrorso the caller can distinguish skippable conditions from real failures. - Tests:
PbpFileTests,PbpHeaderTests,SfoDataTests,SfoEntryTests,TocEntryTests,CueSheetWriterTests, plus real-file integration tests (PbpFileIntegrationTests).