Calculate track sizes and pregaps in media info.

This commit is contained in:
2020-01-02 18:31:49 +00:00
parent ebcb66f376
commit 9bbc70f06e
6 changed files with 136 additions and 80 deletions

View File

@@ -138,8 +138,8 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
// Check subchannels support // Check subchannels support
supportsPqSubchannel = SupportsPqSubchannel(); supportsPqSubchannel = SupportsPqSubchannel(_dev, _dumpLog, UpdateStatus);
supportsRwSubchannel = SupportsRwSubchannel(); supportsRwSubchannel = SupportsRwSubchannel(_dev, _dumpLog, UpdateStatus);
switch(_subchannel) switch(_subchannel)
{ {
@@ -207,8 +207,7 @@ namespace DiscImageChef.Core.Devices.Dumping
if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) && if(!_outputPlugin.SupportedSectorTags.Contains(SectorTagType.CdSectorSubchannel) &&
supportedSubchannel != MmcSubchannel.None) supportedSubchannel != MmcSubchannel.None)
{ {
if(_force || if(_force || _subchannel == DumpSubchannel.None)
_subchannel == DumpSubchannel.None)
{ {
_dumpLog.WriteLine("Output format does not support subchannels, continuing..."); _dumpLog.WriteLine("Output format does not support subchannels, continuing...");
UpdateStatus?.Invoke("Output format does not support subchannels, continuing..."); UpdateStatus?.Invoke("Output format does not support subchannels, continuing...");
@@ -339,13 +338,13 @@ namespace DiscImageChef.Core.Devices.Dumping
blockSize = sectorSize + subSize; blockSize = sectorSize + subSize;
tracks = GetCdTracks(ref blockSize, dskType, out lastSector, leadOutStarts, mediaTags, out toc, trackFlags, tracks = GetCdTracks(ref blockSize, _dev, dskType, _dumpLog, _force, out lastSector, leadOutStarts,
subType); mediaTags, StoppingErrorMessage, subType, out toc, trackFlags, UpdateStatus);
if(tracks is null) if(tracks is null)
return; return;
SolveTrackPregaps(tracks, supportsPqSubchannel, supportsRwSubchannel); SolveTrackPregaps(_dev, _dumpLog, UpdateStatus, tracks, supportsPqSubchannel, supportsRwSubchannel);
for(int t = 1; t < tracks.Length; t++) for(int t = 1; t < tracks.Length; t++)
tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1; tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1;
@@ -872,7 +871,8 @@ namespace DiscImageChef.Core.Devices.Dumping
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, tracks); readcd, sectorsForOffset, subSize, supportedSubchannel, supportsLongSectors, ref totalDuration,
tracks);
// TODO: Enable when underlying images support lead-outs // TODO: Enable when underlying images support lead-outs
/* /*

View File

@@ -35,6 +35,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Core.Logging;
using DiscImageChef.Devices; using DiscImageChef.Devices;
// ReSharper disable JoinDeclarationAndInitializer // ReSharper disable JoinDeclarationAndInitializer
@@ -118,7 +119,8 @@ namespace DiscImageChef.Core.Devices.Dumping
firstTrackPregapMs.Close(); firstTrackPregapMs.Close();
} }
void SolveTrackPregaps(Track[] tracks, bool supportsPqSubchannel, bool supportsRwSubchannel) public static void SolveTrackPregaps(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus,
Track[] tracks, bool supportsPqSubchannel, bool supportsRwSubchannel)
{ {
bool sense; // Sense indicator bool sense; // Sense indicator
byte[] cmdBuf; // Data buffer byte[] cmdBuf; // Data buffer
@@ -136,14 +138,14 @@ namespace DiscImageChef.Core.Devices.Dumping
while(lba > tracks[i - 1].TrackStartSector) while(lba > tracks[i - 1].TrackStartSector)
{ {
if(supportsPqSubchannel) if(supportsPqSubchannel)
sense = _dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.AllTypes, false, false, false, sense = dev.ReadCd(out cmdBuf, out _, lba, 16, 1, MmcSectorTypes.AllTypes, false, false, false,
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16, MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Q16,
_dev.Timeout, out _); dev.Timeout, out _);
else else
{ {
sense = dev.ReadCd(out cmdBuf, out _, lba, 96, 1, MmcSectorTypes.AllTypes, false, false, false, sense = dev.ReadCd(out cmdBuf, out _, lba, 96, 1, MmcSectorTypes.AllTypes, false, false, false,
MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw, MmcHeaderCodes.None, false, false, MmcErrorField.None, MmcSubchannel.Raw,
_dev.Timeout, out _); dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -229,8 +231,8 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
#if DEBUG #if DEBUG
_dumpLog.WriteLine($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors"); dumpLog?.WriteLine($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
UpdateStatus?.Invoke($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors"); updateStatus?.Invoke($"Track {tracks[i].TrackSequence} pregap is {trackPregap} sectors");
#endif #endif
tracks[i].TrackPregap = (ulong)trackPregap; tracks[i].TrackPregap = (ulong)trackPregap;

View File

@@ -30,31 +30,8 @@
// Copyright © 2011-2019 Natalia Portillo // Copyright © 2011-2019 Natalia Portillo
// ****************************************************************************/ // ****************************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Extents;
using DiscImageChef.CommonTypes.Interfaces;
using DiscImageChef.CommonTypes.Metadata;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console;
using DiscImageChef.Core.Logging; using DiscImageChef.Core.Logging;
using DiscImageChef.Core.Media.Detection;
using DiscImageChef.Decoders.CD;
using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Schemas;
using CdOffset = DiscImageChef.Database.Models.CdOffset;
using MediaType = DiscImageChef.CommonTypes.MediaType;
using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID;
using Session = DiscImageChef.Decoders.CD.Session;
using TrackType = DiscImageChef.CommonTypes.Enums.TrackType;
// ReSharper disable JoinDeclarationAndInitializer // ReSharper disable JoinDeclarationAndInitializer
// ReSharper disable InlineOutVariableDeclaration // ReSharper disable InlineOutVariableDeclaration
@@ -64,24 +41,24 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
partial class Dump partial class Dump
{ {
bool SupportsRwSubchannel() public static bool SupportsRwSubchannel(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus)
{ {
_dumpLog.WriteLine("Checking if drive supports full raw subchannel reading..."); dumpLog?.WriteLine("Checking if drive supports full raw subchannel reading...");
UpdateStatus?.Invoke("Checking if drive supports full raw subchannel reading..."); updateStatus?.Invoke("Checking if drive supports full raw subchannel reading...");
return!_dev.ReadCd(out _, out _, 0, 2352 + 96, 1, MmcSectorTypes.AllTypes, false, false, true, return!dev.ReadCd(out _, out _, 0, 2352 + 96, 1, MmcSectorTypes.AllTypes, false, false, true,
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Raw, dev.Timeout,
_dev.Timeout, out _); out _);
} }
bool SupportsPqSubchannel() public static bool SupportsPqSubchannel(Device dev, DumpLog dumpLog, UpdateStatusHandler updateStatus)
{ {
_dumpLog.WriteLine("Checking if drive supports PQ subchannel reading..."); dumpLog?.WriteLine("Checking if drive supports PQ subchannel reading...");
UpdateStatus?.Invoke("Checking if drive supports PQ subchannel reading..."); updateStatus?.Invoke("Checking if drive supports PQ subchannel reading...");
return!_dev.ReadCd(out _, out _, 0, 2352 + 16, 1, MmcSectorTypes.AllTypes, false, false, true, return!dev.ReadCd(out _, out _, 0, 2352 + 16, 1, MmcSectorTypes.AllTypes, false, false, true,
MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, MmcHeaderCodes.AllHeaders, true, true, MmcErrorField.None, MmcSubchannel.Q16, dev.Timeout,
_dev.Timeout, out _); out _);
} }
} }
} }

View File

@@ -36,7 +36,9 @@ using System.Linq;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Core.Logging;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
using DiscImageChef.Devices;
// ReSharper disable JoinDeclarationAndInitializer // ReSharper disable JoinDeclarationAndInitializer
// ReSharper disable InlineOutVariableDeclaration // ReSharper disable InlineOutVariableDeclaration
@@ -48,17 +50,25 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
/// <summary>Reads the TOC, processes it, returns the track list and last sector</summary> /// <summary>Reads the TOC, processes it, returns the track list and last sector</summary>
/// <param name="blockSize">Size of the read sector in bytes</param> /// <param name="blockSize">Size of the read sector in bytes</param>
/// <param name="dev">Device</param>
/// <param name="dskType">Disc type</param> /// <param name="dskType">Disc type</param>
/// <param name="dumpLog">Dump log</param>
/// <param name="force">Force dump enabled</param>
/// <param name="lastSector">Last sector number</param> /// <param name="lastSector">Last sector number</param>
/// <param name="leadOutStarts">Lead-out starts</param> /// <param name="leadOutStarts">Lead-out starts</param>
/// <param name="mediaTags">Media tags</param> /// <param name="mediaTags">Media tags</param>
/// <param name="stoppingErrorMessage">Stopping error message handler</param>
/// <param name="subType">Track subchannel type</param>
/// <param name="toc">Full CD TOC</param> /// <param name="toc">Full CD TOC</param>
/// <param name="trackFlags">Track flags</param> /// <param name="trackFlags">Track flags</param>
/// <param name="subType">Track subchannel type</param> /// <param name="updateStatus">Update status handler</param>
/// <returns>List of tracks</returns> /// <returns>List of tracks</returns>
Track[] GetCdTracks(ref uint blockSize, MediaType dskType, out long lastSector, public static Track[] GetCdTracks(ref uint blockSize, Device dev, MediaType dskType, DumpLog dumpLog,
Dictionary<int, long> leadOutStarts, Dictionary<MediaTagType, byte[]> mediaTags, bool force, out long lastSector, Dictionary<int, long> leadOutStarts,
out FullTOC.CDFullTOC? toc, Dictionary<byte, byte> trackFlags, TrackSubchannelType subType) Dictionary<MediaTagType, byte[]> mediaTags,
ErrorMessageHandler stoppingErrorMessage, TrackSubchannelType subType,
out FullTOC.CDFullTOC? toc, Dictionary<byte, byte> trackFlags,
UpdateStatusHandler updateStatus)
{ {
byte[] cmdBuf = null; // Data buffer byte[] cmdBuf = null; // Data buffer
const uint sectorSize = 2352; // Full sector size const uint sectorSize = 2352; // Full sector size
@@ -71,9 +81,9 @@ namespace DiscImageChef.Core.Devices.Dumping
// We discarded all discs that falsify a TOC before requesting a real TOC // We discarded all discs that falsify a TOC before requesting a real TOC
// No TOC, no CD (or an empty one) // No TOC, no CD (or an empty one)
_dumpLog.WriteLine("Reading full TOC"); dumpLog?.WriteLine("Reading full TOC");
UpdateStatus?.Invoke("Reading full TOC"); updateStatus?.Invoke("Reading full TOC");
sense = _dev.ReadRawToc(out cmdBuf, out _, 0, _dev.Timeout, out _); sense = dev.ReadRawToc(out cmdBuf, out _, 0, dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -83,12 +93,12 @@ namespace DiscImageChef.Core.Devices.Dumping
{ {
tmpBuf = new byte[cmdBuf.Length - 2]; tmpBuf = new byte[cmdBuf.Length - 2];
Array.Copy(cmdBuf, 2, tmpBuf, 0, cmdBuf.Length - 2); Array.Copy(cmdBuf, 2, tmpBuf, 0, cmdBuf.Length - 2);
mediaTags.Add(MediaTagType.CD_FullTOC, tmpBuf); mediaTags?.Add(MediaTagType.CD_FullTOC, tmpBuf);
} }
} }
UpdateStatus?.Invoke("Building track map..."); updateStatus?.Invoke("Building track map...");
_dumpLog.WriteLine("Building track map..."); dumpLog?.WriteLine("Building track map...");
if(toc.HasValue) if(toc.HasValue)
{ {
@@ -113,7 +123,7 @@ namespace DiscImageChef.Core.Devices.Dumping
TrackSubchannelType = subType TrackSubchannelType = subType
}); });
trackFlags.Add(trk.POINT, trk.CONTROL); trackFlags?.Add(trk.POINT, trk.CONTROL);
} }
else if(trk.POINT == 0xA2) else if(trk.POINT == 0xA2)
{ {
@@ -154,7 +164,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
lastSector = ((phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe) - 150; lastSector = ((phour * 3600 * 75) + (pmin * 60 * 75) + (psec * 75) + pframe) - 150;
leadOutStarts.Add(trk.SessionNumber, lastSector + 1); leadOutStarts?.Add(trk.SessionNumber, lastSector + 1);
} }
else if(trk.POINT == 0xA0 && else if(trk.POINT == 0xA0 &&
trk.ADR == 1) trk.ADR == 1)
@@ -181,18 +191,18 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
else else
{ {
UpdateStatus?.Invoke("Cannot read RAW TOC, requesting processed one..."); updateStatus?.Invoke("Cannot read RAW TOC, requesting processed one...");
_dumpLog.WriteLine("Cannot read RAW TOC, requesting processed one..."); dumpLog?.WriteLine("Cannot read RAW TOC, requesting processed one...");
sense = _dev.ReadToc(out cmdBuf, out _, false, 0, _dev.Timeout, out _); sense = dev.ReadToc(out cmdBuf, out _, false, 0, dev.Timeout, out _);
TOC.CDTOC? oldToc = TOC.Decode(cmdBuf); TOC.CDTOC? oldToc = TOC.Decode(cmdBuf);
if((sense || !oldToc.HasValue) && if((sense || !oldToc.HasValue) &&
!_force) !force)
{ {
_dumpLog.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000..."); dumpLog?.WriteLine("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
StoppingErrorMessage?. stoppingErrorMessage?.
Invoke("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000..."); Invoke("Could not read TOC, if you want to continue, use force, and will try from LBA 0 to 360000...");
return null; return null;
@@ -214,7 +224,7 @@ namespace DiscImageChef.Core.Devices.Dumping
TrackRawBytesPerSector = (int)sectorSize, TrackSubchannelType = subType TrackRawBytesPerSector = (int)sectorSize, TrackSubchannelType = subType
}); });
trackFlags.Add(trk.TrackNumber, trk.CONTROL); trackFlags?.Add(trk.TrackNumber, trk.CONTROL);
} }
else if(trk.TrackNumber == 0xAA) else if(trk.TrackNumber == 0xAA)
{ {
@@ -229,8 +239,8 @@ namespace DiscImageChef.Core.Devices.Dumping
if(trackList.Count == 0) if(trackList.Count == 0)
{ {
UpdateStatus?.Invoke("No tracks found, adding a single track from 0 to Lead-Out"); updateStatus?.Invoke("No tracks found, adding a single track from 0 to Lead-Out");
_dumpLog.WriteLine("No tracks found, adding a single track from 0 to Lead-Out"); dumpLog?.WriteLine("No tracks found, adding a single track from 0 to Lead-Out");
trackList.Add(new Track trackList.Add(new Track
{ {
@@ -240,12 +250,12 @@ namespace DiscImageChef.Core.Devices.Dumping
TrackSubchannelType = subType TrackSubchannelType = subType
}); });
trackFlags.Add(1, (byte)(leadoutTrackType == TrackType.Audio ? 0 : 4)); trackFlags?.Add(1, (byte)(leadoutTrackType == TrackType.Audio ? 0 : 4));
} }
if(lastSector == 0) if(lastSector == 0)
{ {
sense = _dev.ReadCapacity16(out cmdBuf, out _, _dev.Timeout, out _); sense = dev.ReadCapacity16(out cmdBuf, out _, dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -258,7 +268,7 @@ namespace DiscImageChef.Core.Devices.Dumping
} }
else else
{ {
sense = _dev.ReadCapacity(out cmdBuf, out _, _dev.Timeout, out _); sense = dev.ReadCapacity(out cmdBuf, out _, dev.Timeout, out _);
if(!sense) if(!sense)
{ {
@@ -269,21 +279,21 @@ namespace DiscImageChef.Core.Devices.Dumping
if(lastSector <= 0) if(lastSector <= 0)
{ {
if(!_force) if(!force)
{ {
StoppingErrorMessage?. stoppingErrorMessage?.
Invoke("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors..."); Invoke("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
_dumpLog. dumpLog?.
WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors..."); WriteLine("Could not find Lead-Out, if you want to continue use force option and will continue until 360000 sectors...");
return null; return null;
} }
UpdateStatus?. updateStatus?.
Invoke("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); Invoke("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
_dumpLog.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before..."); dumpLog?.WriteLine("WARNING: Could not find Lead-Out start, will try to read up to 360000 sectors, probably will fail before...");
lastSector = 360000; lastSector = 360000;
} }
} }

View File

@@ -33,15 +33,20 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.Invocation; using System.CommandLine.Invocation;
using System.Linq;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Database;
using DiscImageChef.Database.Models;
using DiscImageChef.Decoders.ATA; using DiscImageChef.Decoders.ATA;
using DiscImageChef.Decoders.PCMCIA; using DiscImageChef.Decoders.PCMCIA;
using DiscImageChef.Decoders.SCSI; using DiscImageChef.Decoders.SCSI;
using DiscImageChef.Decoders.SCSI.MMC; using DiscImageChef.Decoders.SCSI.MMC;
using DiscImageChef.Decoders.SCSI.SSC; using DiscImageChef.Decoders.SCSI.SSC;
using DiscImageChef.Devices; using DiscImageChef.Devices;
using Command = System.CommandLine.Command;
using Device = DiscImageChef.Devices.Device;
using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo; using DeviceInfo = DiscImageChef.Core.Devices.Info.DeviceInfo;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
@@ -1066,6 +1071,33 @@ namespace DiscImageChef.Commands
dev.Close(); dev.Close();
DicConsole.WriteLine();
// Open master database
var ctx = DicContext.Create(Settings.Settings.MasterDbPath);
// Search for device in master database
Database.Models.Device dbDev =
ctx.Devices.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model &&
d.Revision == dev.Revision);
if(dbDev is null)
DicConsole.WriteLine("Device not in database, please create a device report and attach it to a Github issue.");
else
{
DicConsole.WriteLine($"Device in database since {dbDev.LastSynchronized}.");
if(dbDev.OptimalMultipleSectorsRead > 0)
DicConsole.WriteLine($"Optimal multiple read is {dbDev.LastSynchronized} sectors.");
}
// Search for read offset in master database
CdOffset cdOffset =
ctx.CdOffsets.FirstOrDefault(d => d.Manufacturer == dev.Manufacturer && d.Model == dev.Model);
DicConsole.WriteLine(cdOffset is null ? "CD reading offset not found in database."
: $"CD reading offset is {cdOffset.Offset} samples ({cdOffset.Offset * 4} bytes).");
return(int)ErrorNumber.NoError; return(int)ErrorNumber.NoError;
} }
} }

View File

@@ -35,8 +35,10 @@ using System.Collections.Generic;
using System.CommandLine; using System.CommandLine;
using System.CommandLine.Invocation; using System.CommandLine.Invocation;
using DiscImageChef.CommonTypes.Enums; using DiscImageChef.CommonTypes.Enums;
using DiscImageChef.CommonTypes.Structs;
using DiscImageChef.Console; using DiscImageChef.Console;
using DiscImageChef.Core; using DiscImageChef.Core;
using DiscImageChef.Core.Devices.Dumping;
using DiscImageChef.Core.Media.Info; using DiscImageChef.Core.Media.Info;
using DiscImageChef.Decoders.Bluray; using DiscImageChef.Decoders.Bluray;
using DiscImageChef.Decoders.CD; using DiscImageChef.Decoders.CD;
@@ -50,6 +52,7 @@ using BCA = DiscImageChef.Decoders.Bluray.BCA;
using Cartridge = DiscImageChef.Decoders.DVD.Cartridge; using Cartridge = DiscImageChef.Decoders.DVD.Cartridge;
using DDS = DiscImageChef.Decoders.DVD.DDS; using DDS = DiscImageChef.Decoders.DVD.DDS;
using DMI = DiscImageChef.Decoders.Xbox.DMI; using DMI = DiscImageChef.Decoders.Xbox.DMI;
using Session = DiscImageChef.Decoders.CD.Session;
using Spare = DiscImageChef.Decoders.DVD.Spare; using Spare = DiscImageChef.Decoders.DVD.Spare;
namespace DiscImageChef.Commands namespace DiscImageChef.Commands
@@ -530,6 +533,38 @@ namespace DiscImageChef.Commands
DicConsole.WriteLine("Media identified as {0}", scsiInfo.MediaType); DicConsole.WriteLine("Media identified as {0}", scsiInfo.MediaType);
Statistics.AddMedia(scsiInfo.MediaType, true); Statistics.AddMedia(scsiInfo.MediaType, true);
if(scsiInfo.Toc != null ||
scsiInfo.RawToc != null)
{
uint blockSize = 2352;
Track[] tracks = Dump.GetCdTracks(ref blockSize, dev, scsiInfo.MediaType, null, false,
out long lastSector, null, null, null, TrackSubchannelType.None,
out _, null, null);
if(tracks != null)
{
bool supportsPqSubchannel = Dump.SupportsPqSubchannel(dev, null, null);
bool supportsRwSubchannel = Dump.SupportsRwSubchannel(dev, null, null);
Dump.SolveTrackPregaps(dev, null, null, tracks, supportsPqSubchannel, supportsRwSubchannel);
for(int t = 1; t < tracks.Length; t++)
tracks[t - 1].TrackEndSector = tracks[t].TrackStartSector - 1;
tracks[tracks.Length - 1].TrackEndSector = (ulong)lastSector;
DicConsole.WriteLine();
DicConsole.WriteLine("Track calculations:");
foreach(Track track in tracks)
DicConsole.
WriteLine("Track {0} starts at LBA {1}, ends at LBA {2}, has a pregap of {3} sectors and is of type {4}",
track.TrackSequence, track.TrackStartSector, track.TrackEndSector,
track.TrackPregap, track.TrackType);
}
}
dev.Close(); dev.Close();
} }
} }