From afaacd20e828990149f54450666273dfeb51095b Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 7 Jun 2021 20:47:05 +0100 Subject: [PATCH] Fix sectors calculations in CDRWin disc images. Fixes #501 --- Aaru.Images/CDRWin/CDRWin.cs | 1 - Aaru.Images/CDRWin/Properties.cs | 41 +--------- Aaru.Images/CDRWin/Read.cs | 133 +++++++++++++++++++------------ 3 files changed, 84 insertions(+), 91 deletions(-) diff --git a/Aaru.Images/CDRWin/CDRWin.cs b/Aaru.Images/CDRWin/CDRWin.cs index 6a072a22e..e8fcf918f 100644 --- a/Aaru.Images/CDRWin/CDRWin.cs +++ b/Aaru.Images/CDRWin/CDRWin.cs @@ -44,7 +44,6 @@ namespace Aaru.DiscImages { IFilter _cdrwinFilter; StreamReader _cueStream; - ulong _densitySeparationSectors; StreamWriter _descriptorStream; CdrWinDisc _discImage; ImageInfo _imageInfo; diff --git a/Aaru.Images/CDRWin/Properties.cs b/Aaru.Images/CDRWin/Properties.cs index 224a87fd6..fee3ccfff 100644 --- a/Aaru.Images/CDRWin/Properties.cs +++ b/Aaru.Images/CDRWin/Properties.cs @@ -131,46 +131,7 @@ namespace Aaru.DiscImages else aaruTrack.TrackSubchannelType = TrackSubchannelType.None; - if(_imageInfo.MediaType != MediaType.CD && - _imageInfo.MediaType != MediaType.CDDA && - _imageInfo.MediaType != MediaType.CDG && - _imageInfo.MediaType != MediaType.CDEG && - _imageInfo.MediaType != MediaType.CDI && - _imageInfo.MediaType != MediaType.CDROM && - _imageInfo.MediaType != MediaType.CDROMXA && - _imageInfo.MediaType != MediaType.CDPLUS && - _imageInfo.MediaType != MediaType.CDMO && - _imageInfo.MediaType != MediaType.CDR && - _imageInfo.MediaType != MediaType.CDRW && - _imageInfo.MediaType != MediaType.CDMRW && - _imageInfo.MediaType != MediaType.VCD && - _imageInfo.MediaType != MediaType.SVCD && - _imageInfo.MediaType != MediaType.PCD && - _imageInfo.MediaType != MediaType.DTSCD && - _imageInfo.MediaType != MediaType.CDMIDI && - _imageInfo.MediaType != MediaType.CDV && - _imageInfo.MediaType != MediaType.CDIREADY && - _imageInfo.MediaType != MediaType.FMTOWNS && - _imageInfo.MediaType != MediaType.PS1CD && - _imageInfo.MediaType != MediaType.PS2CD && - _imageInfo.MediaType != MediaType.MEGACD && - _imageInfo.MediaType != MediaType.SATURNCD && - _imageInfo.MediaType != MediaType.GDROM && - _imageInfo.MediaType != MediaType.GDR && - _imageInfo.MediaType != MediaType.MilCD && - _imageInfo.MediaType != MediaType.SuperCDROM2 && - _imageInfo.MediaType != MediaType.JaguarCD && - _imageInfo.MediaType != MediaType.ThreeDO && - _imageInfo.MediaType != MediaType.PCFX && - _imageInfo.MediaType != MediaType.NeoGeoCD && - _imageInfo.MediaType != MediaType.CDTV && - _imageInfo.MediaType != MediaType.CD32 && - _imageInfo.MediaType != MediaType.Playdia && - _imageInfo.MediaType != MediaType.Pippin && - _imageInfo.MediaType != MediaType.VideoNow && - _imageInfo.MediaType != MediaType.VideoNowColor && - _imageInfo.MediaType != MediaType.VideoNowXp && - _imageInfo.MediaType != MediaType.CVD) + if(!_isCd) { aaruTrack.TrackPregap = 0; aaruTrack.Indexes?.Clear(); diff --git a/Aaru.Images/CDRWin/Read.cs b/Aaru.Images/CDRWin/Read.cs index 45dadb5f2..5f7ee0143 100644 --- a/Aaru.Images/CDRWin/Read.cs +++ b/Aaru.Images/CDRWin/Read.cs @@ -164,7 +164,6 @@ namespace Aaru.DiscImages bool firstTrackInSession = false; ulong gdRomSession2Offset = 45000; - _densitySeparationSectors = 0; while(_cueStream.Peek() >= 0) { @@ -898,9 +897,10 @@ namespace Aaru.DiscImages if(leadouts.TryGetValue((byte)s, out int leadout)) { + int startSector; sessions[s - 1].EndSector = (ulong)(leadout - 1); - if(!cueTracks[lastSessionTrack].Indexes.TryGetValue(0, out int startSector)) + if(!cueTracks[lastSessionTrack].Indexes.TryGetValue(0, out startSector)) cueTracks[lastSessionTrack].Indexes.TryGetValue(1, out startSector); cueTracks[lastSessionTrack].Sectors = (ulong)(leadout - startSector); @@ -915,26 +915,23 @@ namespace Aaru.DiscImages if(firstSessionTrack.Pregap < 150) firstSessionTrack.Pregap = 150; - if(cueTracks.All(i => i.TrackFile.DataFilter.GetFilename() == + if(cueTracks.Any(i => i.TrackFile.DataFilter.GetFilename() != cueTracks.First().TrackFile.DataFilter.GetFilename())) + continue; + + if(firstSessionTrack.Indexes.TryGetValue(0, out int sessionStart)) { - if(firstSessionTrack.Indexes.TryGetValue(0, out int sessionStart)) - { - sessions[s - 1].StartSector = (ulong)sessionStart; + sessions[s - 1].StartSector = (ulong)sessionStart; - continue; - } + continue; + } - if(firstSessionTrack.Indexes.TryGetValue(1, out sessionStart)) - { - sessions[s - 1].StartSector = (ulong)sessionStart; - } + if(firstSessionTrack.Indexes.TryGetValue(1, out sessionStart)) + { + sessions[s - 1].StartSector = (ulong)sessionStart; } } - for(int s = 1; s <= sessions.Length; s++) - _discImage.Sessions.Add(sessions[s - 1]); - for(int t = 1; t <= cueTracks.Length; t++) { if(cueTracks[t - 1].Indexes.TryGetValue(0, out int idx0) && @@ -957,7 +954,7 @@ namespace Aaru.DiscImages // We check 32 random positions, to prevent coincidence of data for(int i = 0; i < 32; i++) { - int next = rnd.Next((int)_imageInfo.Sectors); + int next = rnd.Next(cueTracks[^1].Indexes[1]); track1Stream.Position = next * 2352; byte[] data = new byte[16]; @@ -1056,9 +1053,9 @@ namespace Aaru.DiscImages _discImage.MediaType = MediaType.CDG; else if(cdi) _discImage.MediaType = MediaType.CDI; - else if(firstAudio && - data && - _discImage.Sessions.Count > 1 && + else if(firstAudio && + data && + sessions.Length > 1 && mode2) _discImage.MediaType = MediaType.CDPLUS; else if((firstData && audio) || mode2) @@ -1138,26 +1135,6 @@ namespace Aaru.DiscImages else AaruConsole.DebugWriteLine("CDRWin plugin", "\tComment: \"{0}\"", _discImage.Comment); - AaruConsole.DebugWriteLine("CDRWin plugin", "Session information:"); - AaruConsole.DebugWriteLine("CDRWin plugin", "\tDisc contains {0} sessions", _discImage.Sessions.Count); - - for(int i = 0; i < _discImage.Sessions.Count; i++) - { - AaruConsole.DebugWriteLine("CDRWin plugin", "\tSession {0} information:", i + 1); - - AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tStarting track: {0}", - _discImage.Sessions[i].StartTrack); - - AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tStarting sector: {0}", - _discImage.Sessions[i].StartSector); - - AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tEnding track: {0}", - _discImage.Sessions[i].EndTrack); - - AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tEnding sector: {0}", - _discImage.Sessions[i].EndSector); - } - AaruConsole.DebugWriteLine("CDRWin plugin", "Track information:"); AaruConsole.DebugWriteLine("CDRWin plugin", "\tDisc contains {0} tracks", _discImage.Tracks.Count); @@ -1235,6 +1212,50 @@ namespace Aaru.DiscImages AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tTitle: {0}", _discImage.Tracks[i].Title); } + foreach(CdrWinTrack track in _discImage.Tracks) + _imageInfo.ImageSize += track.Bps * track.Sectors; + + for(int s = 0; s < sessions.Length; s++) + { + if(!_discImage.Tracks[(int)sessions[s].StartTrack - 1].Indexes. + TryGetValue(0, out int sessionTrackStart)) + _discImage.Tracks[(int)sessions[s].StartTrack - 1].Indexes. + TryGetValue(1, out sessionTrackStart); + + sessions[s].StartSector = (ulong)(sessionTrackStart > 0 ? sessionTrackStart : 0); + + if(!_discImage.Tracks[(int)sessions[s].EndTrack - 1].Indexes.TryGetValue(0, out sessionTrackStart)) + _discImage.Tracks[(int)sessions[s].EndTrack - 1].Indexes.TryGetValue(1, out sessionTrackStart); + + sessions[s].EndSector = (ulong)(sessionTrackStart > 0 ? sessionTrackStart : 0); + sessions[s].EndSector += _discImage.Tracks[(int)sessions[s].EndTrack - 1].Sectors - 1; + } + + for(int s = 1; s <= sessions.Length; s++) + _discImage.Sessions.Add(sessions[s - 1]); + + _imageInfo.Sectors = _discImage.Sessions.OrderByDescending(s => s.EndSector).First().EndSector + 1; + + AaruConsole.DebugWriteLine("CDRWin plugin", "Session information:"); + AaruConsole.DebugWriteLine("CDRWin plugin", "\tDisc contains {0} sessions", _discImage.Sessions.Count); + + for(int i = 0; i < _discImage.Sessions.Count; i++) + { + AaruConsole.DebugWriteLine("CDRWin plugin", "\tSession {0} information:", i + 1); + + AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tStarting track: {0}", + _discImage.Sessions[i].StartTrack); + + AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tStarting sector: {0}", + _discImage.Sessions[i].StartSector); + + AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tEnding track: {0}", + _discImage.Sessions[i].EndTrack); + + AaruConsole.DebugWriteLine("CDRWin plugin", "\t\tEnding sector: {0}", + _discImage.Sessions[i].EndSector); + } + AaruConsole.DebugWriteLine("CDRWin plugin", "Building offset map"); Partitions = new List(); @@ -1280,8 +1301,7 @@ namespace Aaru.DiscImages _discImage.Tracks[i].Sequence == 3) { _offsetMap.Add(_discImage.Tracks[i].Sequence, gdRomSession2Offset); - _densitySeparationSectors += gdRomSession2Offset - previousPartitionsSize; - previousPartitionsSize = gdRomSession2Offset; + previousPartitionsSize = gdRomSession2Offset; } else if(_discImage.Tracks[i].Sequence > 1) _offsetMap.Add(_discImage.Tracks[i].Sequence, @@ -1309,14 +1329,6 @@ namespace Aaru.DiscImages AaruConsole.DebugWriteLine("CDRWin plugin", "\tPartition size in bytes: {0}", partition.Size); } - foreach(CdrWinTrack track in _discImage.Tracks) - _imageInfo.ImageSize += track.Bps * track.Sectors; - - foreach(CdrWinTrack track in _discImage.Tracks) - _imageInfo.Sectors += track.Sectors; - - _imageInfo.Sectors += _densitySeparationSectors; - if(_discImage.MediaType != MediaType.CDROMXA && _discImage.MediaType != MediaType.CDDA && _discImage.MediaType != MediaType.CDI && @@ -1346,7 +1358,7 @@ namespace Aaru.DiscImages // Detect ISOBuster extensions else if(_discImage.OriginalMediaType != null || _discImage.Comment.ToLower().Contains("isobuster") || - _discImage.Sessions.Count > 1) + sessions.Length > 1) _imageInfo.Application = "ISOBuster"; else _imageInfo.Application = "CDRWin"; @@ -1465,6 +1477,27 @@ namespace Aaru.DiscImages _imageInfo.ReadableSectorTags.Remove(SectorTagType.CdSectorEdc); _imageInfo.ReadableSectorTags.Remove(SectorTagType.CdTrackFlags); _imageInfo.ReadableSectorTags.Remove(SectorTagType.CdTrackIsrc); + + sessions = _discImage.Sessions.ToArray(); + + foreach(CdrWinTrack track in _discImage.Tracks) + { + track.Indexes.Remove(0); + track.Pregap = 0; + + for(int s = 0; s < sessions.Length; s++) + { + if(sessions[s].SessionSequence > 1 && + track.Sequence == sessions[s].StartTrack) + { + track.TrackFile.Offset += 307200; + track.Sectors -= 150; + sessions[s].StartSector = (ulong)track.Indexes[1]; + } + } + } + + _discImage.Sessions = sessions.ToList(); } return true;