Add error detection and possible correction when dumping CD-i Ready.

This commit is contained in:
2026-07-06 03:12:06 +01:00
parent 056518bfd6
commit c91123949a

View File

@@ -37,6 +37,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Aaru.Checksums;
using Aaru.CommonTypes.AaruMetadata;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Extents;
@@ -114,7 +115,6 @@ partial class Dump
}
// TODO: Set pregap for Track 1
// TODO: Detect errors in sectors
/// <summary>Reads all the hidden track in CD-i Ready discs</summary>
/// <param name="blocks">Total number of positive sectors</param>
/// <param name="blockSize">Size of the read sector in bytes</param>
@@ -297,6 +297,9 @@ partial class Dump
if(cdiReadyReadAsAudio) data = Sector.Scramble(data);
// Fix or leave as is because we're overcoming track mode change
CdChecksums.FixSector(data);
outputOptical.WriteSectorsLong(data,
i + r,
false,
@@ -388,6 +391,8 @@ partial class Dump
extents.Add(i, blocksToRead, true);
_writeStopwatch.Restart();
List<ulong> paintBad = [];
if(supportedSubchannel != MmcSubchannel.None)
{
var data = new byte[sectorSize * blocksToRead];
@@ -400,10 +405,29 @@ partial class Dump
{
Array.Copy(cmdBuf, (int)(0 + b * blockSize), tmpData, 0, sectorSize);
tmpData = Sector.Scramble(tmpData);
SectorFixResult fixedStatus = CdChecksums.FixSector(tmpData);
if(fixedStatus == SectorFixResult.CouldNotFix) // Damaged
{
_resume.BadBlocks.Add(i + (ulong)b);
paintBad.Add(i + (ulong)b);
}
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
}
else
Array.Copy(cmdBuf, (int)(0 + b * blockSize), data, sectorSize * b, sectorSize);
{
Array.Copy(cmdBuf, (int)(0 + b * blockSize), tmpData, 0, sectorSize);
SectorFixResult fixedStatus = CdChecksums.FixSector(tmpData);
if(fixedStatus == SectorFixResult.CouldNotFix) // Damaged
{
_resume.BadBlocks.Add(i + (ulong)b);
paintBad.Add(i + (ulong)b);
}
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
}
Array.Copy(cmdBuf, (int)(sectorSize + b * blockSize), sub, subSize * b, subSize);
}
@@ -453,33 +477,50 @@ partial class Dump
}
else
{
var tmpData = new byte[sectorSize];
var data = new byte[sectorSize * blocksToRead];
var status = new SectorStatus[blocksToRead];
if(cdiReadyReadAsAudio)
{
var tmpData = new byte[sectorSize];
var data = new byte[sectorSize * blocksToRead];
for(var b = 0; b < blocksToRead; b++)
{
status[b] = SectorStatus.Dumped;
Array.Copy(cmdBuf, (int)(b * sectorSize), tmpData, 0, sectorSize);
tmpData = Sector.Scramble(tmpData);
SectorFixResult fixedStatus = CdChecksums.FixSector(tmpData);
if(fixedStatus == SectorFixResult.CouldNotFix) // Damaged
{
_resume.BadBlocks.Add(i + (ulong)b);
paintBad.Add(i + (ulong)b);
status[b] = SectorStatus.Errored;
}
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
}
outputOptical.WriteSectorsLong(data,
i,
false,
blocksToRead,
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
.ToArray());
outputOptical.WriteSectorsLong(data, i, false, blocksToRead, status);
}
else
{
outputOptical.WriteSectorsLong(cmdBuf,
i,
false,
blocksToRead,
Enumerable.Repeat(SectorStatus.Dumped, (int)blocksToRead)
.ToArray());
for(var b = 0; b < blocksToRead; b++)
{
status[b] = SectorStatus.Dumped;
Array.Copy(cmdBuf, (int)(b * sectorSize), tmpData, 0, sectorSize);
SectorFixResult fixedStatus = CdChecksums.FixSector(tmpData);
if(fixedStatus == SectorFixResult.CouldNotFix) // Damaged
{
_resume.BadBlocks.Add(i + (ulong)b);
paintBad.Add(i + (ulong)b);
status[b] = SectorStatus.Errored;
}
Array.Copy(tmpData, 0, data, sectorSize * b, sectorSize);
}
outputOptical.WriteSectorsLong(cmdBuf, i, false, blocksToRead, status);
}
}