Handle discs that have pregap ending in LBA 1 instead of ending in LBA 0.

This commit is contained in:
2020-07-18 20:43:37 +01:00
parent 4b78302630
commit b0f01f53f0
9 changed files with 179 additions and 69 deletions

View File

@@ -147,7 +147,7 @@ namespace Aaru.Core.Devices.Dumping
MmcSubchannel supportedSubchannel, ref double totalDuration, Track[] tracks, MmcSubchannel supportedSubchannel, ref double totalDuration, Track[] tracks,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
ref string mcn, HashSet<int> subchannelExtents, ulong blocks, bool cdiReadyReadAsAudio, ref string mcn, HashSet<int> subchannelExtents, ulong blocks, bool cdiReadyReadAsAudio,
int offsetBytes, int sectorsForOffset) int offsetBytes, int sectorsForOffset, Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
ulong sectorSpeedStart = 0; // Used to calculate correct speed ulong sectorSpeedStart = 0; // Used to calculate correct speed
DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation
@@ -270,9 +270,16 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i + r, 1); _outputPlugin.WriteSectorsLong(data, i + r, 1);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i + r, 1, subLog, isrcs, 1, ref mcn, tracks, desiredSubchannel, sub,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, i + r, 1, subLog, isrcs,
_fixSubchannelCrc, _dumpLog, UpdateStatus); 1, ref mcn, tracks,
subchannelExtents,
_fixSubchannelPosition,
_outputPlugin,
_fixSubchannel,
_fixSubchannelCrc,
_dumpLog, UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
@@ -355,9 +362,15 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, blocksToRead); _outputPlugin.WriteSectorsLong(data, i, blocksToRead);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, blocksToRead, subLog, isrcs, 1, ref mcn, tracks, desiredSubchannel, sub, i,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, blocksToRead, subLog, isrcs, 1,
_fixSubchannelCrc, _dumpLog, UpdateStatus); ref mcn, tracks,
subchannelExtents,
_fixSubchannelPosition,
_outputPlugin, _fixSubchannel,
_fixSubchannelCrc, _dumpLog,
UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)

View File

@@ -86,7 +86,8 @@ namespace Aaru.Core.Devices.Dumping
bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize, bool read12, bool read16, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration, MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel,
Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents) Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
ulong sectorSpeedStart = 0; // Used to calculate correct speed ulong sectorSpeedStart = 0; // Used to calculate correct speed
DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation DateTime timeSpeedStart = DateTime.UtcNow; // Time of start for speed calculation
@@ -407,7 +408,8 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin, _outputPlugin,
_fixSubchannel, _fixSubchannel,
_fixSubchannelCrc, _fixSubchannelCrc,
_dumpLog, UpdateStatus); _dumpLog, UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
@@ -546,7 +548,8 @@ namespace Aaru.Core.Devices.Dumping
_fixSubchannelPosition, _fixSubchannelPosition,
_outputPlugin, _fixSubchannel, _outputPlugin, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, _fixSubchannelCrc, _dumpLog,
UpdateStatus); UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)

View File

@@ -119,6 +119,7 @@ namespace Aaru.Core.Devices.Dumping
bool cdiReadyReadAsAudio = false; bool cdiReadyReadAsAudio = false;
Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags Dictionary<MediaTagType, byte[]> mediaTags = new Dictionary<MediaTagType, byte[]>(); // Media tags
Dictionary<byte, int> smallestPregapLbaPerTrack = new Dictionary<byte, int>();
MediaType dskType = MediaType.CD; MediaType dskType = MediaType.CD;
@@ -406,7 +407,7 @@ namespace Aaru.Core.Devices.Dumping
} }
if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. if(!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStorePregaps) && CanStorePregaps) &&
tracks.Where(track => track.TrackSequence != tracks.Where(track => track.TrackSequence !=
tracks.First(t => t.TrackSession == track.TrackSession).TrackSequence). tracks.First(t => t.TrackSession == track.TrackSession).TrackSequence).
Any(track => track.TrackPregap > 0)) Any(track => track.TrackPregap > 0))
@@ -795,7 +796,7 @@ namespace Aaru.Core.Devices.Dumping
// If a subchannel is supported, check if output plugin allows us to write it. // If a subchannel is supported, check if output plugin allows us to write it.
if(desiredSubchannel != MmcSubchannel.None && if(desiredSubchannel != MmcSubchannel.None &&
!(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities. !(_outputPlugin as IWritableOpticalImage).OpticalCapabilities.HasFlag(OpticalImageCapabilities.
CanStoreSubchannelRw)) CanStoreSubchannelRw))
{ {
_dumpLog.WriteLine("Output image does not support subchannels, {0}continuing...", _force ? "" : "not "); _dumpLog.WriteLine("Output image does not support subchannels, {0}continuing...", _force ? "" : "not ");
@@ -1128,20 +1129,22 @@ namespace Aaru.Core.Devices.Dumping
ReadCdiReady(blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration, ReadCdiReady(blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration,
leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, subSize, supportedSubchannel, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, subSize, supportedSubchannel,
ref totalDuration, tracks, subLog, desiredSubchannel, isrcs, ref mcn, ref totalDuration, tracks, subLog, desiredSubchannel, isrcs, ref mcn,
subchannelExtents, blocks, cdiReadyReadAsAudio, offsetBytes, sectorsForOffset); subchannelExtents, blocks, cdiReadyReadAsAudio, offsetBytes, sectorsForOffset,
smallestPregapLbaPerTrack);
} }
ReadCdData(audioExtents, blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ReadCdData(audioExtents, blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog,
ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, ref imageWriteDuration, lastSector, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed,
out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16, out newTrim, tracks[0].TrackType != TrackType.Audio, offsetBytes, read6, read10, read12, read16,
readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration,
tracks, subLog, desiredSubchannel, isrcs, ref mcn, subchannelExtents); tracks, subLog, desiredSubchannel, isrcs, ref mcn, subchannelExtents, smallestPregapLbaPerTrack);
// TODO: Enable when underlying images support lead-outs // TODO: Enable when underlying images support lead-outs
/* /*
DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration, DumpCdLeadOuts(blocks, blockSize, ref currentSpeed, currentTry, extents, ibgLog, ref imageWriteDuration,
leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, read6, read10, read12, read16, readcd, leadOutExtents, ref maxSpeed, mhddLog, ref minSpeed, read6, read10, read12, read16, readcd,
supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs, ref mcn, tracks); supportedSubchannel, subSize, ref totalDuration, subLog, desiredSubchannel, isrcs, ref mcn, tracks,
smallestPregapLbaPerTrack);
*/ */
end = DateTime.UtcNow; end = DateTime.UtcNow;
@@ -1168,11 +1171,12 @@ namespace Aaru.Core.Devices.Dumping
TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12, TrimCdUserData(audioExtents, blockSize, currentTry, extents, newTrim, offsetBytes, read6, read10, read12,
read16, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, read16, readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors,
ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, ref mcn, subchannelExtents); ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, ref mcn, subchannelExtents,
smallestPregapLbaPerTrack);
RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset, RetryCdUserData(audioExtents, blockSize, currentTry, extents, offsetBytes, readcd, sectorsForOffset,
subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs, subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, tracks, isrcs,
ref mcn, subchannelExtents); ref mcn, subchannelExtents, smallestPregapLbaPerTrack);
foreach(Tuple<ulong, ulong> leadoutExtent in leadOutExtents.ToArray()) foreach(Tuple<ulong, ulong> leadoutExtent in leadOutExtents.ToArray())
{ {
@@ -1184,7 +1188,7 @@ namespace Aaru.Core.Devices.Dumping
_retryPasses > 0 && _retryPasses > 0 &&
_retrySubchannel) _retrySubchannel)
RetrySubchannel(readcd, subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel, RetrySubchannel(readcd, subSize, supportedSubchannel, ref totalDuration, subLog, desiredSubchannel,
tracks, isrcs, ref mcn, subchannelExtents); tracks, isrcs, ref mcn, subchannelExtents, smallestPregapLbaPerTrack);
// Write media tags to image // Write media tags to image
if(!_aborted) if(!_aborted)

View File

@@ -55,7 +55,8 @@ namespace Aaru.Core.Devices.Dumping
ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize, ExtentsULong extents, int offsetBytes, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog, MmcSubchannel supportedSubchannel, ref double totalDuration, SubchannelLog subLog,
MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary<byte, string> isrcs, MmcSubchannel desiredSubchannel, Track[] tracks, Dictionary<byte, string> isrcs,
ref string mcn, HashSet<int> subchannelExtents) ref string mcn, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
@@ -293,9 +294,15 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.TrackSequence, ref mcn, desiredSubchannel, sub, badSector, 1,
tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, subLog, isrcs,
_fixSubchannelCrc, _dumpLog, UpdateStatus); (byte)track.TrackSequence, ref mcn,
tracks, subchannelExtents,
_fixSubchannelPosition,
_outputPlugin, _fixSubchannel,
_fixSubchannelCrc, _dumpLog,
UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
@@ -412,9 +419,17 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorLong(data, badSector); _outputPlugin.WriteSectorLong(data, badSector);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, badSector, 1, subLog, isrcs, (byte)track.TrackSequence, desiredSubchannel, sub,
ref mcn, tracks, subchannelExtents, _fixSubchannelPosition, _outputPlugin, badSector, 1, subLog, isrcs,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus); (byte)track.TrackSequence,
ref mcn, tracks,
subchannelExtents,
_fixSubchannelPosition,
_outputPlugin,
_fixSubchannel,
_fixSubchannelCrc, _dumpLog,
UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
@@ -458,7 +473,8 @@ namespace Aaru.Core.Devices.Dumping
void RetrySubchannel(bool readcd, uint subSize, MmcSubchannel supportedSubchannel, ref double totalDuration, void RetrySubchannel(bool readcd, uint subSize, MmcSubchannel supportedSubchannel, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents) Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
bool sense = true; // Sense indicator bool sense = true; // Sense indicator
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
@@ -559,7 +575,8 @@ namespace Aaru.Core.Devices.Dumping
Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5, Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, desiredSubchannel, cmdBuf, badSector, 5,
subLog, isrcs, (byte)track.TrackSequence, ref mcn, tracks, subLog, isrcs, (byte)track.TrackSequence, ref mcn, tracks,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, subchannelExtents, _fixSubchannelPosition, _outputPlugin,
_fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus); _fixSubchannel, _fixSubchannelCrc, _dumpLog, UpdateStatus,
smallestPregapLbaPerTrack);
if(subchannelExtents.Contains(tmpArray[i])) if(subchannelExtents.Contains(tmpArray[i]))
continue; continue;

View File

@@ -75,7 +75,8 @@ namespace Aaru.Core.Devices.Dumping
bool read6, bool read10, bool read12, bool read16, bool readcd, bool read6, bool read10, bool read12, bool read16, bool readcd,
MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration, MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
ref string mcn, Track[] tracks, HashSet<int> subchannelExtents) ref string mcn, Track[] tracks, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -161,9 +162,16 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks, desiredSubchannel, sub, i,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, _maximumReadable, subLog,
_fixSubchannelCrc, _dumpLog, UpdateStatus); isrcs, 0xAA, ref mcn, tracks,
subchannelExtents,
_fixSubchannelPosition,
_outputPlugin,
_fixSubchannel,
_fixSubchannelCrc, _dumpLog,
UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)
@@ -244,7 +252,8 @@ namespace Aaru.Core.Devices.Dumping
bool read6, bool read10, bool read12, bool read16, bool readcd, bool read6, bool read10, bool read12, bool read16, bool readcd,
MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration, MmcSubchannel supportedSubchannel, uint subSize, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Dictionary<byte, string> isrcs,
ref string mcn, Track[] tracks, HashSet<int> subchannelExtents) ref string mcn, Track[] tracks, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -330,9 +339,16 @@ namespace Aaru.Core.Devices.Dumping
_outputPlugin.WriteSectorsLong(data, i, _maximumReadable); _outputPlugin.WriteSectorsLong(data, i, _maximumReadable);
bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel, bool indexesChanged = Media.CompactDisc.WriteSubchannelToImage(supportedSubchannel,
desiredSubchannel, sub, i, _maximumReadable, subLog, isrcs, 0xAA, ref mcn, tracks, desiredSubchannel, sub, i,
subchannelExtents, _fixSubchannelPosition, _outputPlugin, _fixSubchannel, _maximumReadable, subLog,
_fixSubchannelCrc, _dumpLog, UpdateStatus); isrcs, 0xAA, ref mcn, tracks,
subchannelExtents,
_fixSubchannelPosition,
_outputPlugin,
_fixSubchannel,
_fixSubchannelCrc, _dumpLog,
UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(indexesChanged) if(indexesChanged)

View File

@@ -53,7 +53,8 @@ namespace Aaru.Core.Devices.Dumping
bool read16, bool readcd, int sectorsForOffset, uint subSize, bool read16, bool readcd, int sectorsForOffset, uint subSize,
MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration, MmcSubchannel supportedSubchannel, bool supportsLongSectors, ref double totalDuration,
SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks, SubchannelLog subLog, MmcSubchannel desiredSubchannel, Track[] tracks,
Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents) Dictionary<byte, string> isrcs, ref string mcn, HashSet<int> subchannelExtents,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
DateTime start; DateTime start;
DateTime end; DateTime end;
@@ -201,7 +202,8 @@ namespace Aaru.Core.Devices.Dumping
_fixSubchannelPosition, _fixSubchannelPosition,
_outputPlugin, _fixSubchannel, _outputPlugin, _fixSubchannel,
_fixSubchannelCrc, _dumpLog, _fixSubchannelCrc, _dumpLog,
UpdateStatus); UpdateStatus,
smallestPregapLbaPerTrack);
// Set tracks and go back // Set tracks and go back
if(!indexesChanged) if(!indexesChanged)

View File

@@ -20,7 +20,8 @@ namespace Aaru.Core.Media
Track[] tracks, HashSet<int> subchannelExtents, Track[] tracks, HashSet<int> subchannelExtents,
bool fixSubchannelPosition, IWritableImage outputPlugin, bool fixSubchannelPosition, IWritableImage outputPlugin,
bool fixSubchannel, bool fixSubchannelCrc, DumpLog dumpLog, bool fixSubchannel, bool fixSubchannelCrc, DumpLog dumpLog,
UpdateStatusHandler updateStatus) UpdateStatusHandler updateStatus,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
if(supportedSubchannel == MmcSubchannel.Q16) if(supportedSubchannel == MmcSubchannel.Q16)
sub = Subchannel.ConvertQToRaw(sub); sub = Subchannel.ConvertQToRaw(sub);
@@ -34,8 +35,8 @@ namespace Aaru.Core.Media
byte[] deSub = Subchannel.Deinterleave(sub); byte[] deSub = Subchannel.Deinterleave(sub);
bool indexesChanged = bool indexesChanged = CheckIndexesFromSubchannel(deSub, isrcs, currentTrack, ref mcn, tracks, dumpLog,
CheckIndexesFromSubchannel(deSub, isrcs, currentTrack, ref mcn, tracks, dumpLog, updateStatus); updateStatus, smallestPregapLbaPerTrack);
if(!fixSubchannelPosition || if(!fixSubchannelPosition ||
desiredSubchannel == MmcSubchannel.None) desiredSubchannel == MmcSubchannel.None)
@@ -228,7 +229,8 @@ namespace Aaru.Core.Media
static bool CheckIndexesFromSubchannel(byte[] deSub, Dictionary<byte, string> isrcs, byte currentTrack, static bool CheckIndexesFromSubchannel(byte[] deSub, Dictionary<byte, string> isrcs, byte currentTrack,
ref string mcn, Track[] tracks, DumpLog dumpLog, ref string mcn, Track[] tracks, DumpLog dumpLog,
UpdateStatusHandler updateStatus) UpdateStatusHandler updateStatus,
Dictionary<byte, int> smallestPregapLbaPerTrack)
{ {
bool status = false; bool status = false;
@@ -314,12 +316,34 @@ namespace Aaru.Core.Media
byte pframe = (byte)(((q[5] / 16) * 10) + (q[5] & 0x0F)); byte pframe = (byte)(((q[5] / 16) * 10) + (q[5] & 0x0F));
int qPos = (pmin * 60 * 75) + (psec * 75) + pframe; int qPos = (pmin * 60 * 75) + (psec * 75) + pframe;
if(!smallestPregapLbaPerTrack.ContainsKey(trackNo))
smallestPregapLbaPerTrack[trackNo] = 1;
if(qPos < smallestPregapLbaPerTrack[trackNo])
{
int dif = smallestPregapLbaPerTrack[trackNo] - qPos;
tracks[i].TrackPregap += (ulong)dif;
tracks[i].TrackStartSector -= (ulong)dif;
smallestPregapLbaPerTrack[trackNo] = qPos;
if(i > 0)
tracks[i - 1].TrackEndSector = tracks[i].TrackStartSector - 1;
dumpLog?.
WriteLine($"Pregap for track {trackNo} set to {tracks[i].TrackPregap} sectors.");
updateStatus?.
Invoke($"Pregap for track {trackNo} set to {tracks[i].TrackPregap} sectors.");
status = true;
}
if(tracks[i].TrackPregap >= (ulong)qPos) if(tracks[i].TrackPregap >= (ulong)qPos)
continue; continue;
ulong oldPregap = tracks[i].TrackPregap; ulong oldPregap = tracks[i].TrackPregap;
tracks[i].TrackPregap = (ulong)qPos + 1; tracks[i].TrackPregap = (ulong)qPos;
tracks[i].TrackStartSector -= tracks[i].TrackPregap - oldPregap; tracks[i].TrackStartSector -= tracks[i].TrackPregap - oldPregap;
if(i > 0) if(i > 0)

View File

@@ -1010,10 +1010,11 @@ namespace Aaru.Gui.ViewModels.Windows
Progress2Value = Progress2MaxValue; Progress2Value = Progress2MaxValue;
}); });
Dictionary<byte, string> isrcs = new Dictionary<byte, string>(); Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>(); Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>();
string mcn = null; string mcn = null;
HashSet<int> subchannelExtents = new HashSet<int>(); HashSet<int> subchannelExtents = new HashSet<int>();
Dictionary<byte, int> smallestPregapLbaPerTrack = new Dictionary<byte, int>();
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags. foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.
Where(t => t == SectorTagType.CdTrackIsrc).OrderBy(t => t)) Where(t => t == SectorTagType.CdTrackIsrc).OrderBy(t => t))
@@ -1119,9 +1120,14 @@ namespace Aaru.Gui.ViewModels.Windows
track != null) track != null)
{ {
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors, 1, null, isrcs, MmcSubchannel.Raw, sector,
(byte)track.TrackSequence, ref mcn, tracks.ToArray(), subchannelExtents, false, doneSectors, 1, null, isrcs,
outputFormat, false, false, null, null); (byte)track.TrackSequence,
ref mcn, tracks.ToArray(),
subchannelExtents, false,
outputFormat, false, false,
null, null,
smallestPregapLbaPerTrack);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());
@@ -1141,9 +1147,15 @@ namespace Aaru.Gui.ViewModels.Windows
{ {
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors, sectorsToDo, null, isrcs, MmcSubchannel.Raw, sector,
(byte)track.TrackSequence, ref mcn, tracks.ToArray(), subchannelExtents, false, doneSectors, sectorsToDo, null,
outputFormat, false, false, null, null); isrcs,
(byte)track.TrackSequence,
ref mcn, tracks.ToArray(),
subchannelExtents, false,
outputFormat, false, false,
null, null,
smallestPregapLbaPerTrack);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());

View File

@@ -496,8 +496,8 @@ namespace Aaru.Commands.Image
// Try name // Try name
else else
candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, format, candidates.AddRange(plugins.WritableImages.Values.Where(t => string.Equals(t.Name, format,
StringComparison. StringComparison.
InvariantCultureIgnoreCase))); InvariantCultureIgnoreCase)));
if(candidates.Count == 0) if(candidates.Count == 0)
{ {
@@ -660,7 +660,7 @@ namespace Aaru.Commands.Image
sectorsToDo = (uint)(trackSectors - doneSectors); sectorsToDo = (uint)(trackSectors - doneSectors);
AaruConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)", AaruConsole.Write("\rConverting sectors {0} to {1} in track {3} ({2:P2} done)",
doneSectors + track.TrackStartSector, doneSectors + track.TrackStartSector,
doneSectors + sectorsToDo + track.TrackStartSector, doneSectors + sectorsToDo + track.TrackStartSector,
(doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors, (doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors,
track.TrackSequence); track.TrackSequence);
@@ -737,11 +737,12 @@ namespace Aaru.Commands.Image
AaruConsole.WriteLine(); AaruConsole.WriteLine();
Dictionary<byte, string> isrcs = new Dictionary<byte, string>(); Dictionary<byte, string> isrcs = new Dictionary<byte, string>();
Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>(); Dictionary<byte, byte> trackFlags = new Dictionary<byte, byte>();
string mcn = null; string mcn = null;
HashSet<int> subchannelExtents = new HashSet<int>(); HashSet<int> subchannelExtents = new HashSet<int>();
Track[] tracks = inputOptical.Tracks.ToArray(); Track[] tracks = inputOptical.Tracks.ToArray();
Dictionary<byte, int> smallestPregapLbaPerTrack = new Dictionary<byte, int>();
foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags. foreach(SectorTagType tag in inputFormat.Info.ReadableSectorTags.
Where(t => t == SectorTagType.CdTrackIsrc).OrderBy(t => t)) Where(t => t == SectorTagType.CdTrackIsrc).OrderBy(t => t))
@@ -844,7 +845,7 @@ namespace Aaru.Commands.Image
sectorsToDo = (uint)(trackSectors - doneSectors); sectorsToDo = (uint)(trackSectors - doneSectors);
AaruConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)", AaruConsole.Write("\rConverting tag {4} for sectors {0} to {1} in track {3} ({2:P2} done)",
doneSectors + track.TrackStartSector, doneSectors + track.TrackStartSector,
doneSectors + sectorsToDo + track.TrackStartSector, doneSectors + sectorsToDo + track.TrackStartSector,
(doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors, (doneSectors + track.TrackStartSector) / (double)inputFormat.Info.Sectors,
track.TrackSequence, tag); track.TrackSequence, tag);
@@ -856,10 +857,19 @@ namespace Aaru.Commands.Image
if(tag == SectorTagType.CdSectorSubchannel) if(tag == SectorTagType.CdSectorSubchannel)
{ {
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors + track.TrackStartSector, 1, null, MmcSubchannel.Raw, sector,
isrcs, (byte)track.TrackSequence, ref mcn, tracks, subchannelExtents, doneSectors +
fixSubchannelPosition, outputFormat, fixSubchannel, fixSubchannelCrc, null, track.TrackStartSector, 1,
null); null, isrcs,
(byte)track.TrackSequence,
ref mcn, tracks,
subchannelExtents,
fixSubchannelPosition,
outputFormat,
fixSubchannel,
fixSubchannelCrc, null,
null,
smallestPregapLbaPerTrack);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());
@@ -878,10 +888,19 @@ namespace Aaru.Commands.Image
if(tag == SectorTagType.CdSectorSubchannel) if(tag == SectorTagType.CdSectorSubchannel)
{ {
bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw, bool indexesChanged = CompactDisc.WriteSubchannelToImage(MmcSubchannel.Raw,
MmcSubchannel.Raw, sector, doneSectors + track.TrackStartSector, MmcSubchannel.Raw, sector,
sectorsToDo, null, isrcs, (byte)track.TrackSequence, ref mcn, tracks, doneSectors +
subchannelExtents, fixSubchannelPosition, outputFormat, fixSubchannel, track.TrackStartSector,
fixSubchannelCrc, null, null); sectorsToDo, null, isrcs,
(byte)track.TrackSequence,
ref mcn, tracks,
subchannelExtents,
fixSubchannelPosition,
outputFormat,
fixSubchannel,
fixSubchannelCrc, null,
null,
smallestPregapLbaPerTrack);
if(indexesChanged) if(indexesChanged)
outputOptical.SetTracks(tracks.ToList()); outputOptical.SetTracks(tracks.ToList());