mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Save metadata in CDRWin cuesheet.
This commit is contained in:
@@ -41,43 +41,31 @@ namespace DiscImageChef.DiscImages
|
||||
// TODO: Implement track flags
|
||||
public partial class CdrWin : IWritableOpticalImage, IVerifiableImage
|
||||
{
|
||||
IFilter cdrwinFilter;
|
||||
StreamReader cueStream;
|
||||
StreamWriter descriptorStream;
|
||||
CdrWinDisc discimage;
|
||||
ImageInfo imageInfo;
|
||||
Stream imageStream;
|
||||
IFilter _cdrwinFilter;
|
||||
StreamReader _cueStream;
|
||||
StreamWriter _descriptorStream;
|
||||
CdrWinDisc _discImage;
|
||||
ImageInfo _imageInfo;
|
||||
Stream _imageStream;
|
||||
/// <summary>Dictionary, index is track #, value is TrackFile</summary>
|
||||
Dictionary<uint, ulong> offsetmap;
|
||||
bool separateTracksWriting;
|
||||
Dictionary<byte, byte> trackFlags;
|
||||
Dictionary<byte, string> trackIsrcs;
|
||||
string writingBaseName;
|
||||
Dictionary<uint, FileStream> writingStreams;
|
||||
List<Track> writingTracks;
|
||||
Dictionary<uint, ulong> _offsetMap;
|
||||
bool _separateTracksWriting;
|
||||
Dictionary<byte, byte> _trackFlags;
|
||||
Dictionary<byte, string> _trackIsrcs;
|
||||
string _writingBaseName;
|
||||
Dictionary<uint, FileStream> _writingStreams;
|
||||
List<Track> _writingTracks;
|
||||
|
||||
public CdrWin()
|
||||
public CdrWin() => _imageInfo = new ImageInfo
|
||||
{
|
||||
imageInfo = new ImageInfo
|
||||
{
|
||||
ReadableSectorTags = new List<SectorTagType>(),
|
||||
ReadableMediaTags = new List<MediaTagType>(),
|
||||
HasPartitions = true,
|
||||
HasSessions = true,
|
||||
Version = null,
|
||||
ReadableSectorTags = new List<SectorTagType>(), ReadableMediaTags = new List<MediaTagType>(),
|
||||
HasPartitions = true, HasSessions = true, Version = null,
|
||||
ApplicationVersion = null,
|
||||
MediaTitle = null,
|
||||
Creator = null,
|
||||
MediaManufacturer = null,
|
||||
MediaTitle = null, Creator = null, MediaManufacturer = null,
|
||||
MediaModel = null,
|
||||
MediaPartNumber = null,
|
||||
MediaSequence = 0,
|
||||
LastMediaSequence = 0,
|
||||
MediaPartNumber = null, MediaSequence = 0, LastMediaSequence = 0,
|
||||
DriveManufacturer = null,
|
||||
DriveModel = null,
|
||||
DriveSerialNumber = null,
|
||||
DriveFirmwareRevision = null
|
||||
DriveModel = null, DriveSerialNumber = null, DriveFirmwareRevision = null
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,6 +137,7 @@ namespace DiscImageChef.DiscImages
|
||||
const string REGEX_SESSION = @"\bREM\s+SESSION\s+(?<number>\d+).*$";
|
||||
const string REGEX_MEDIA_TYPE = @"\bREM\s+ORIGINAL MEDIA-TYPE:\s+(?<mediatype>.+)$";
|
||||
const string REGEX_LEAD_OUT = @"\bREM\s+LEAD-OUT\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||
|
||||
// Not checked
|
||||
const string REGEX_LBA = @"\bREM MSF:\s+(?<msf>[\d]+:[\d]+:[\d]+)\s+=\s+LBA:\s+(?<lba>[\d]+)$";
|
||||
const string REGEX_DISC_ID = @"\bDISC_ID\s+(?<diskid>[\da-f]{8})$";
|
||||
@@ -157,6 +158,7 @@ namespace DiscImageChef.DiscImages
|
||||
const string REGEX_PREGAP = @"\bPREGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||
const string REGEX_POSTGAP = @"\bPOSTGAP\s+(?<msf>[\d]+:[\d]+:[\d]+)$";
|
||||
const string REGEX_FLAGS = @"\bFLAGS\s+(((?<dcp>DCP)|(?<quad>4CH)|(?<pre>PRE)|(?<scms>SCMS))\s*)+$";
|
||||
|
||||
// Trurip extensions
|
||||
const string REGEX_APPLICATION = @"\bREM\s+Ripping Tool:\s+(?<application>.+)$";
|
||||
const string REGEX_TRURIP_DISC_HASHES = @"\bREM\s+DISC\s+HASHES$";
|
||||
@@ -169,5 +171,9 @@ namespace DiscImageChef.DiscImages
|
||||
const string REGEX_TRURIP_TRACK_MD5 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{32}$";
|
||||
const string REGEX_TRURIP_TRACK_SHA1 = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{40}$";
|
||||
const string REGEX_TRURIP_TRACK_UNKNOWN = @"\bREM\s+(Gap|Trk)\s+(?<number>\d{2}):\s+[\da-f]{8,}$";
|
||||
const string REGEX_DIC_MEDIA_TYPE = @"\bREM\s+METADATA DIC MEDIA-TYPE:\s+(?<mediatype>.+)$";
|
||||
const string REGEX_APPLICATION_VERSION = @"\bREM\s+Ripping Tool Version:\s+(?<application>.+)$";
|
||||
const string REGEX_DUMP_EXTENT =
|
||||
@"\bREM\s+METADATA DUMP EXTENT:\s+(?<application>.+)\s+\|\s+(?<version>.+)\s+\|\s+(?<os>.+)\s+\|\s+(?<manufacturer>.+)\s+\|\s+(?<model>.+)\s+\|\s+(?<firmware>.+)\s+\|\s+(?<serial>.+)\s+\|\s+(?<start>\d+):(?<end>\d+)$";
|
||||
}
|
||||
}
|
||||
@@ -38,14 +38,14 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
public partial class CdrWin
|
||||
{
|
||||
static ulong CdrWinMsftoLba(string msf)
|
||||
static ulong CdrWinMsfToLba(string msf)
|
||||
{
|
||||
string[] msfElements = msf.Split(':');
|
||||
ulong minute = ulong.Parse(msfElements[0]);
|
||||
ulong second = ulong.Parse(msfElements[1]);
|
||||
ulong frame = ulong.Parse(msfElements[2]);
|
||||
|
||||
ulong sectors = minute * 60 * 75 + second * 75 + frame;
|
||||
ulong sectors = (minute * 60 * 75) + (second * 75) + frame;
|
||||
|
||||
return sectors;
|
||||
}
|
||||
@@ -144,8 +144,8 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
}
|
||||
|
||||
static (byte minute, byte second, byte frame) LbaToMsf(ulong sector) =>
|
||||
((byte)(sector / 75 / 60), (byte)(sector / 75 % 60), (byte)(sector % 75));
|
||||
static(byte minute, byte second, byte frame) LbaToMsf(ulong sector) =>
|
||||
((byte)(sector / 75 / 60), (byte)((sector / 75) % 60), (byte)(sector % 75));
|
||||
|
||||
static string GetTrackMode(Track track)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ namespace DiscImageChef.DiscImages
|
||||
case MediaType.HDDVDROM: return CDRWIN_DISK_TYPE_HDDVD;
|
||||
case MediaType.HDDVDRW: return CDRWIN_DISK_TYPE_HDDVDRW;
|
||||
case MediaType.HDDVDRWDL: return CDRWIN_DISK_TYPE_HDDVDRWDL;
|
||||
default: return "";
|
||||
default: return"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace DiscImageChef.DiscImages
|
||||
// Due to .cue format, this method must parse whole file, ignoring errors (those will be thrown by OpenImage()).
|
||||
public bool Identify(IFilter imageFilter)
|
||||
{
|
||||
cdrwinFilter = imageFilter;
|
||||
_cdrwinFilter = imageFilter;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -51,35 +51,43 @@ namespace DiscImageChef.DiscImages
|
||||
byte[] testArray = new byte[512];
|
||||
imageFilter.GetDataForkStream().Read(testArray, 0, 512);
|
||||
imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin);
|
||||
|
||||
// Check for unexpected control characters that shouldn't be present in a text file and can crash this plugin
|
||||
bool twoConsecutiveNulls = false;
|
||||
|
||||
for(int i = 0; i < 512; i++)
|
||||
{
|
||||
if(i >= imageFilter.GetDataForkStream().Length) break;
|
||||
if(i >= imageFilter.GetDataForkStream().Length)
|
||||
break;
|
||||
|
||||
if(testArray[i] == 0)
|
||||
{
|
||||
if(twoConsecutiveNulls) return false;
|
||||
if(twoConsecutiveNulls)
|
||||
return false;
|
||||
|
||||
twoConsecutiveNulls = true;
|
||||
}
|
||||
else twoConsecutiveNulls = false;
|
||||
else
|
||||
twoConsecutiveNulls = false;
|
||||
|
||||
if(testArray[i] < 0x20 && testArray[i] != 0x0A && testArray[i] != 0x0D && testArray[i] != 0x00)
|
||||
if(testArray[i] < 0x20 &&
|
||||
testArray[i] != 0x0A &&
|
||||
testArray[i] != 0x0D &&
|
||||
testArray[i] != 0x00)
|
||||
return false;
|
||||
}
|
||||
|
||||
cueStream = new StreamReader(cdrwinFilter.GetDataForkStream());
|
||||
_cueStream = new StreamReader(_cdrwinFilter.GetDataForkStream());
|
||||
|
||||
while(cueStream.Peek() >= 0)
|
||||
while(_cueStream.Peek() >= 0)
|
||||
{
|
||||
string line = cueStream.ReadLine();
|
||||
string line = _cueStream.ReadLine();
|
||||
|
||||
Regex sr = new Regex(REGEX_SESSION);
|
||||
Regex rr = new Regex(REGEX_COMMENT);
|
||||
Regex cr = new Regex(REGEX_MCN);
|
||||
Regex fr = new Regex(REGEX_FILE);
|
||||
Regex tr = new Regex(REGEX_CDTEXT);
|
||||
var sr = new Regex(REGEX_SESSION);
|
||||
var rr = new Regex(REGEX_COMMENT);
|
||||
var cr = new Regex(REGEX_MCN);
|
||||
var fr = new Regex(REGEX_FILE);
|
||||
var tr = new Regex(REGEX_CDTEXT);
|
||||
|
||||
// First line must be SESSION, REM, CATALOG, FILE or CDTEXTFILE.
|
||||
Match sm = sr.Match(line ?? throw new InvalidOperationException());
|
||||
@@ -95,9 +103,10 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", cdrwinFilter);
|
||||
DicConsole.ErrorWriteLine("Exception trying to identify image file {0}", _cdrwinFilter);
|
||||
DicConsole.ErrorWriteLine("Exception: {0}", ex.Message);
|
||||
DicConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,12 +41,13 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
public partial class CdrWin
|
||||
{
|
||||
public ImageInfo Info => imageInfo;
|
||||
public ImageInfo Info => _imageInfo;
|
||||
public string Name => "CDRWin cuesheet";
|
||||
public Guid Id => new Guid("664568B2-15D4-4E64-8A7A-20BDA8B8386F");
|
||||
public string Format => "CDRWin CUESheet";
|
||||
public string Author => "Natalia Portillo";
|
||||
public List<Partition> Partitions { get; private set; }
|
||||
|
||||
public List<Track> Tracks
|
||||
{
|
||||
get
|
||||
@@ -55,36 +56,34 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
ulong previousStartSector = 0;
|
||||
|
||||
foreach(CdrWinTrack cdrTrack in discimage.Tracks)
|
||||
foreach(CdrWinTrack cdrTrack in _discImage.Tracks)
|
||||
{
|
||||
Track dicTrack = new Track
|
||||
var dicTrack = new Track
|
||||
{
|
||||
Indexes = cdrTrack.Indexes,
|
||||
TrackDescription = cdrTrack.Title,
|
||||
TrackStartSector = previousStartSector,
|
||||
TrackPregap = cdrTrack.Pregap,
|
||||
TrackSession = cdrTrack.Session,
|
||||
TrackSequence = cdrTrack.Sequence,
|
||||
TrackType = CdrWinTrackTypeToTrackType(cdrTrack.Tracktype),
|
||||
TrackFile = cdrTrack.Trackfile.Datafilter.GetFilename(),
|
||||
TrackFilter = cdrTrack.Trackfile.Datafilter,
|
||||
TrackFileOffset = cdrTrack.Trackfile.Offset,
|
||||
TrackFileType = cdrTrack.Trackfile.Filetype,
|
||||
TrackRawBytesPerSector = cdrTrack.Bps,
|
||||
TrackBytesPerSector = CdrWinTrackTypeToCookedBytesPerSector(cdrTrack.Tracktype)
|
||||
Indexes = cdrTrack.Indexes, TrackDescription = cdrTrack.Title,
|
||||
TrackStartSector = previousStartSector, TrackPregap = cdrTrack.Pregap,
|
||||
TrackSession = cdrTrack.Session, TrackSequence = cdrTrack.Sequence,
|
||||
TrackType = CdrWinTrackTypeToTrackType(cdrTrack.TrackType),
|
||||
TrackFile = cdrTrack.TrackFile.DataFilter.GetFilename(),
|
||||
TrackFilter = cdrTrack.TrackFile.DataFilter,
|
||||
TrackFileOffset = cdrTrack.TrackFile.Offset,
|
||||
TrackFileType = cdrTrack.TrackFile.FileType, TrackRawBytesPerSector = cdrTrack.Bps,
|
||||
TrackBytesPerSector = CdrWinTrackTypeToCookedBytesPerSector(cdrTrack.TrackType)
|
||||
};
|
||||
dicTrack.TrackEndSector = dicTrack.TrackStartSector + cdrTrack.Sectors - 1;
|
||||
|
||||
dicTrack.TrackEndSector = (dicTrack.TrackStartSector + cdrTrack.Sectors) - 1;
|
||||
|
||||
/*if(!cdrTrack.Indexes.TryGetValue(0, out dicTrack.TrackStartSector))
|
||||
cdrTrack.Indexes.TryGetValue(1, out dicTrack.TrackStartSector);*/
|
||||
if(cdrTrack.Tracktype == CDRWIN_TRACK_TYPE_CDG)
|
||||
if(cdrTrack.TrackType == CDRWIN_TRACK_TYPE_CDG)
|
||||
{
|
||||
dicTrack.TrackSubchannelFilter = cdrTrack.Trackfile.Datafilter;
|
||||
dicTrack.TrackSubchannelFile = cdrTrack.Trackfile.Datafilter.GetFilename();
|
||||
dicTrack.TrackSubchannelOffset = cdrTrack.Trackfile.Offset;
|
||||
dicTrack.TrackSubchannelFilter = cdrTrack.TrackFile.DataFilter;
|
||||
dicTrack.TrackSubchannelFile = cdrTrack.TrackFile.DataFilter.GetFilename();
|
||||
dicTrack.TrackSubchannelOffset = cdrTrack.TrackFile.Offset;
|
||||
dicTrack.TrackSubchannelType = TrackSubchannelType.RawInterleaved;
|
||||
}
|
||||
else dicTrack.TrackSubchannelType = TrackSubchannelType.None;
|
||||
else
|
||||
dicTrack.TrackSubchannelType = TrackSubchannelType.None;
|
||||
|
||||
tracks.Add(dicTrack);
|
||||
previousStartSector = dicTrack.TrackEndSector + 1;
|
||||
@@ -93,39 +92,45 @@ namespace DiscImageChef.DiscImages
|
||||
return tracks;
|
||||
}
|
||||
}
|
||||
public List<Session> Sessions => discimage.Sessions;
|
||||
public List<DumpHardwareType> DumpHardware => null;
|
||||
|
||||
public List<Session> Sessions => _discImage.Sessions;
|
||||
public List<DumpHardwareType> DumpHardware { get; private set; }
|
||||
public CICMMetadataType CicmMetadata => null;
|
||||
public IEnumerable<MediaTagType> SupportedMediaTags => new[] {MediaTagType.CD_MCN, MediaTagType.CD_TEXT};
|
||||
public IEnumerable<SectorTagType> SupportedSectorTags =>
|
||||
new[]
|
||||
public IEnumerable<MediaTagType> SupportedMediaTags => new[]
|
||||
{
|
||||
MediaTagType.CD_MCN, MediaTagType.CD_TEXT
|
||||
};
|
||||
public IEnumerable<SectorTagType> SupportedSectorTags => new[]
|
||||
{
|
||||
SectorTagType.CdSectorEcc, SectorTagType.CdSectorEccP, SectorTagType.CdSectorEccQ,
|
||||
SectorTagType.CdSectorEdc, SectorTagType.CdSectorHeader, SectorTagType.CdSectorSubHeader,
|
||||
SectorTagType.CdSectorSync, SectorTagType.CdTrackFlags, SectorTagType.CdTrackIsrc
|
||||
};
|
||||
public IEnumerable<MediaType> SupportedMediaTypes =>
|
||||
new[]
|
||||
public IEnumerable<MediaType> SupportedMediaTypes => new[]
|
||||
{
|
||||
MediaType.BDR, MediaType.BDRE, MediaType.BDREXL, MediaType.BDROM, MediaType.BDRXL, MediaType.CBHD,
|
||||
MediaType.CD, MediaType.CDDA, MediaType.CDEG, MediaType.CDG, MediaType.CDI, MediaType.CDMIDI,
|
||||
MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA,
|
||||
MediaType.CDRW, MediaType.CDV, MediaType.DDCD, MediaType.DDCDR, MediaType.DDCDRW,
|
||||
MediaType.DVDDownload, MediaType.DVDPR, MediaType.DVDPRDL, MediaType.DVDPRW, MediaType.DVDPRWDL,
|
||||
MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL, MediaType.DVDROM, MediaType.DVDRW,
|
||||
MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD, MediaType.FVD, MediaType.HDDVDR,
|
||||
MediaType.HDDVDRAM, MediaType.HDDVDRDL, MediaType.HDDVDROM, MediaType.HDDVDRW, MediaType.HDDVDRWDL,
|
||||
MediaType.HDVMD, MediaType.HVD, MediaType.JaguarCD, MediaType.MEGACD, MediaType.PS1CD,
|
||||
MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD, MediaType.PS4BD,
|
||||
MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD, MediaType.ThreeDO,
|
||||
MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD, MediaType.VCDHD,
|
||||
MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon,
|
||||
MediaType.CDMRW, MediaType.CDPLUS, MediaType.CDR, MediaType.CDROM, MediaType.CDROMXA, MediaType.CDRW,
|
||||
MediaType.CDV, MediaType.DDCD, MediaType.DDCDR, MediaType.DDCDRW, MediaType.DVDDownload, MediaType.DVDPR,
|
||||
MediaType.DVDPRDL, MediaType.DVDPRW, MediaType.DVDPRWDL, MediaType.DVDR, MediaType.DVDRAM, MediaType.DVDRDL,
|
||||
MediaType.DVDROM, MediaType.DVDRW, MediaType.DVDRWDL, MediaType.EVD, MediaType.FDDVD, MediaType.DTSCD,
|
||||
MediaType.FVD, MediaType.HDDVDR, MediaType.HDDVDRAM, MediaType.HDDVDRDL, MediaType.HDDVDROM,
|
||||
MediaType.HDDVDRW, MediaType.HDDVDRWDL, MediaType.HDVMD, MediaType.HVD, MediaType.JaguarCD,
|
||||
MediaType.MEGACD, MediaType.PS1CD, MediaType.PS2CD, MediaType.PS2DVD, MediaType.PS3BD, MediaType.PS3DVD,
|
||||
MediaType.PS4BD, MediaType.SuperCDROM2, MediaType.SVCD, MediaType.SVOD, MediaType.SATURNCD,
|
||||
MediaType.ThreeDO, MediaType.UDO, MediaType.UDO2, MediaType.UDO2_WORM, MediaType.UMD, MediaType.VCD,
|
||||
MediaType.VCDHD, MediaType.NeoGeoCD, MediaType.PCFX, MediaType.CDTV, MediaType.CD32, MediaType.Nuon,
|
||||
MediaType.Playdia, MediaType.Pippin, MediaType.FMTOWNS, MediaType.MilCD, MediaType.VideoNow,
|
||||
MediaType.VideoNowColor, MediaType.VideoNowXp
|
||||
};
|
||||
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions =>
|
||||
new[] {("separate", typeof(bool), "Write each track to a separate file.", (object)false)};
|
||||
public IEnumerable<string> KnownExtensions => new[] {".cue"};
|
||||
public IEnumerable<(string name, Type type, string description, object @default)> SupportedOptions => new[]
|
||||
{
|
||||
("separate", typeof(bool), "Write each track to a separate file.", (object)false)
|
||||
};
|
||||
public IEnumerable<string> KnownExtensions => new[]
|
||||
{
|
||||
".cue"
|
||||
};
|
||||
public bool IsWriting { get; private set; }
|
||||
public string ErrorMessage { get; private set; }
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -44,11 +44,11 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>Track #</summary>
|
||||
public uint Sequence;
|
||||
/// <summary>Filter of file containing track</summary>
|
||||
public IFilter Datafilter;
|
||||
public IFilter DataFilter;
|
||||
/// <summary>Offset of track start in file</summary>
|
||||
public ulong Offset;
|
||||
/// <summary>Type of file</summary>
|
||||
public string Filetype;
|
||||
public string FileType;
|
||||
}
|
||||
|
||||
struct CdrWinTrack
|
||||
@@ -70,18 +70,18 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>Track ISRC</summary>
|
||||
public string Isrc;
|
||||
/// <summary>File struct for this track</summary>
|
||||
public CdrWinTrackFile Trackfile;
|
||||
public CdrWinTrackFile TrackFile;
|
||||
/// <summary>Indexes on this track</summary>
|
||||
public Dictionary<int, ulong> Indexes;
|
||||
/// <summary>Track pre-gap in sectors</summary>
|
||||
public ulong Pregap;
|
||||
/// <summary>Track post-gap in sectors</summary>
|
||||
public ulong Postgap;
|
||||
/// <summary>Digical Copy Permitted</summary>
|
||||
/// <summary>Digital Copy Permitted</summary>
|
||||
public bool FlagDcp;
|
||||
/// <summary>Track is quadraphonic</summary>
|
||||
public bool Flag4ch;
|
||||
/// <summary>Track has preemphasis</summary>
|
||||
/// <summary>Track has pre-emphasis</summary>
|
||||
public bool FlagPre;
|
||||
/// <summary>Track has SCMS</summary>
|
||||
public bool FlagScms;
|
||||
@@ -90,7 +90,7 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>Sectors in track</summary>
|
||||
public ulong Sectors;
|
||||
/// <summary>Track type</summary>
|
||||
public string Tracktype;
|
||||
public string TrackType;
|
||||
/// <summary>Track session</summary>
|
||||
public ushort Session;
|
||||
}
|
||||
@@ -112,11 +112,11 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>Media catalog number</summary>
|
||||
public string Mcn;
|
||||
/// <summary>Disk type</summary>
|
||||
public MediaType Disktype;
|
||||
public MediaType MediaType;
|
||||
/// <summary>Disk type string</summary>
|
||||
public string Disktypestr;
|
||||
public string OriginalMediaType;
|
||||
/// <summary>Disk CDDB ID</summary>
|
||||
public string DiskId;
|
||||
public string DiscId;
|
||||
/// <summary>Disk UPC/EAN</summary>
|
||||
public string Barcode;
|
||||
/// <summary>Sessions</summary>
|
||||
@@ -126,11 +126,13 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>Disk comment</summary>
|
||||
public string Comment;
|
||||
/// <summary>File containing CD-Text</summary>
|
||||
public string Cdtextfile;
|
||||
public string CdTextFile;
|
||||
/// <summary>Has trurip extensions</summary>
|
||||
public bool IsTrurip;
|
||||
/// <summary>Disc image hashes</summary>
|
||||
public Dictionary<string, string> DiscHashes;
|
||||
/// <summary>DIC media type</summary>
|
||||
public string DicMediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,27 +44,28 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
public bool? VerifyMediaImage()
|
||||
{
|
||||
if(discimage.DiscHashes.Count == 0) return null;
|
||||
if(_discImage.DiscHashes.Count == 0)
|
||||
return null;
|
||||
|
||||
// Read up to 1MiB at a time for verification
|
||||
const int VERIFY_SIZE = 1024 * 1024;
|
||||
// Read up to 1 MiB at a time for verification
|
||||
const int verifySize = 1024 * 1024;
|
||||
long readBytes;
|
||||
byte[] verifyBytes;
|
||||
|
||||
IFilter[] filters = discimage.Tracks.OrderBy(t => t.Sequence).Select(t => t.Trackfile.Datafilter).Distinct()
|
||||
.ToArray();
|
||||
IFilter[] filters = _discImage.Tracks.OrderBy(t => t.Sequence).Select(t => t.TrackFile.DataFilter).
|
||||
Distinct().ToArray();
|
||||
|
||||
if(discimage.DiscHashes.TryGetValue("sha1", out string sha1))
|
||||
if(_discImage.DiscHashes.TryGetValue("sha1", out string sha1))
|
||||
{
|
||||
Sha1Context ctx = new Sha1Context();
|
||||
var ctx = new Sha1Context();
|
||||
|
||||
foreach(IFilter filter in filters)
|
||||
{
|
||||
Stream stream = filter.GetDataForkStream();
|
||||
readBytes = 0;
|
||||
verifyBytes = new byte[VERIFY_SIZE];
|
||||
verifyBytes = new byte[verifySize];
|
||||
|
||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
||||
while(readBytes + verifySize < stream.Length)
|
||||
{
|
||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||
ctx.Update(verifyBytes);
|
||||
@@ -83,17 +84,17 @@ namespace DiscImageChef.DiscImages
|
||||
return verifySha1 == sha1;
|
||||
}
|
||||
|
||||
if(discimage.DiscHashes.TryGetValue("md5", out string md5))
|
||||
if(_discImage.DiscHashes.TryGetValue("md5", out string md5))
|
||||
{
|
||||
Md5Context ctx = new Md5Context();
|
||||
var ctx = new Md5Context();
|
||||
|
||||
foreach(IFilter filter in filters)
|
||||
{
|
||||
Stream stream = filter.GetDataForkStream();
|
||||
readBytes = 0;
|
||||
verifyBytes = new byte[VERIFY_SIZE];
|
||||
verifyBytes = new byte[verifySize];
|
||||
|
||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
||||
while(readBytes + verifySize < stream.Length)
|
||||
{
|
||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||
ctx.Update(verifyBytes);
|
||||
@@ -112,17 +113,17 @@ namespace DiscImageChef.DiscImages
|
||||
return verifyMd5 == md5;
|
||||
}
|
||||
|
||||
if(discimage.DiscHashes.TryGetValue("crc32", out string crc32))
|
||||
if(_discImage.DiscHashes.TryGetValue("crc32", out string crc32))
|
||||
{
|
||||
Crc32Context ctx = new Crc32Context();
|
||||
var ctx = new Crc32Context();
|
||||
|
||||
foreach(IFilter filter in filters)
|
||||
{
|
||||
Stream stream = filter.GetDataForkStream();
|
||||
readBytes = 0;
|
||||
verifyBytes = new byte[VERIFY_SIZE];
|
||||
verifyBytes = new byte[verifySize];
|
||||
|
||||
while(readBytes + VERIFY_SIZE < stream.Length)
|
||||
while(readBytes + verifySize < stream.Length)
|
||||
{
|
||||
stream.Read(verifyBytes, 0, verifyBytes.Length);
|
||||
ctx.Update(verifyBytes);
|
||||
@@ -141,7 +142,7 @@ namespace DiscImageChef.DiscImages
|
||||
return verifyCrc == crc32;
|
||||
}
|
||||
|
||||
foreach(string hash in discimage.DiscHashes.Keys)
|
||||
foreach(string hash in _discImage.DiscHashes.Keys)
|
||||
DicConsole.DebugWriteLine("CDRWin plugin", "Found unsupported hash {0}", hash);
|
||||
|
||||
return null;
|
||||
@@ -150,6 +151,7 @@ namespace DiscImageChef.DiscImages
|
||||
public bool? VerifySector(ulong sectorAddress)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress);
|
||||
|
||||
return CdChecksums.CheckCdSector(buffer);
|
||||
}
|
||||
|
||||
@@ -171,14 +173,17 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
case null:
|
||||
unknownLbas.Add((ulong)i + sectorAddress);
|
||||
|
||||
break;
|
||||
case false:
|
||||
failingLbas.Add((ulong)i + sectorAddress);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(unknownLbas.Count > 0) return null;
|
||||
if(unknownLbas.Count > 0)
|
||||
return null;
|
||||
|
||||
return failingLbas.Count <= 0;
|
||||
}
|
||||
@@ -201,14 +206,17 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
case null:
|
||||
unknownLbas.Add((ulong)i + sectorAddress);
|
||||
|
||||
break;
|
||||
case false:
|
||||
failingLbas.Add((ulong)i + sectorAddress);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(unknownLbas.Count > 0) return null;
|
||||
if(unknownLbas.Count > 0)
|
||||
return null;
|
||||
|
||||
return failingLbas.Count <= 0;
|
||||
}
|
||||
@@ -216,6 +224,7 @@ namespace DiscImageChef.DiscImages
|
||||
public bool? VerifySector(ulong sectorAddress, uint track)
|
||||
{
|
||||
byte[] buffer = ReadSectorLong(sectorAddress, track);
|
||||
|
||||
return CdChecksums.CheckCdSector(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,32 +51,32 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
if(options.TryGetValue("separate", out string tmpValue))
|
||||
{
|
||||
if(!bool.TryParse(tmpValue, out separateTracksWriting))
|
||||
if(!bool.TryParse(tmpValue, out _separateTracksWriting))
|
||||
{
|
||||
ErrorMessage = "Invalid value for split option";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(separateTracksWriting)
|
||||
if(_separateTracksWriting)
|
||||
{
|
||||
ErrorMessage = "Separate tracksnot yet implemented";
|
||||
ErrorMessage = "Separate tracks not yet implemented";
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
separateTracksWriting = false;
|
||||
_separateTracksWriting = false;
|
||||
|
||||
if(!SupportedMediaTypes.Contains(mediaType))
|
||||
{
|
||||
ErrorMessage = $"Unsupport media format {mediaType}";
|
||||
ErrorMessage = $"Unsupported media format {mediaType}";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
imageInfo = new ImageInfo
|
||||
_imageInfo = new ImageInfo
|
||||
{
|
||||
MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors
|
||||
};
|
||||
@@ -84,8 +84,8 @@ namespace DiscImageChef.DiscImages
|
||||
// TODO: Separate tracks
|
||||
try
|
||||
{
|
||||
writingBaseName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path));
|
||||
descriptorStream = new StreamWriter(path, false, Encoding.ASCII);
|
||||
_writingBaseName = Path.Combine(Path.GetDirectoryName(path), Path.GetFileNameWithoutExtension(path));
|
||||
_descriptorStream = new StreamWriter(path, false, Encoding.ASCII);
|
||||
}
|
||||
catch(IOException e)
|
||||
{
|
||||
@@ -94,13 +94,13 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
discimage = new CdrWinDisc
|
||||
_discImage = new CdrWinDisc
|
||||
{
|
||||
Disktype = mediaType, Sessions = new List<Session>(), Tracks = new List<CdrWinTrack>()
|
||||
MediaType = mediaType, Sessions = new List<Session>(), Tracks = new List<CdrWinTrack>()
|
||||
};
|
||||
|
||||
trackFlags = new Dictionary<byte, byte>();
|
||||
trackIsrcs = new Dictionary<byte, string>();
|
||||
_trackFlags = new Dictionary<byte, byte>();
|
||||
_trackIsrcs = new Dictionary<byte, string>();
|
||||
|
||||
IsWriting = true;
|
||||
ErrorMessage = null;
|
||||
@@ -120,15 +120,15 @@ namespace DiscImageChef.DiscImages
|
||||
switch(tag)
|
||||
{
|
||||
case MediaTagType.CD_MCN:
|
||||
discimage.Mcn = Encoding.ASCII.GetString(data);
|
||||
_discImage.Mcn = Encoding.ASCII.GetString(data);
|
||||
|
||||
return true;
|
||||
case MediaTagType.CD_TEXT:
|
||||
var cdTextStream = new FileStream(writingBaseName + "_cdtext.bin", FileMode.Create,
|
||||
var cdTextStream = new FileStream(_writingBaseName + "_cdtext.bin", FileMode.Create,
|
||||
FileAccess.ReadWrite, FileShare.None);
|
||||
|
||||
cdTextStream.Write(data, 0, data.Length);
|
||||
discimage.Cdtextfile = Path.GetFileName(cdTextStream.Name);
|
||||
_discImage.CdTextFile = Path.GetFileName(cdTextStream.Name);
|
||||
cdTextStream.Close();
|
||||
|
||||
return true;
|
||||
@@ -149,7 +149,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
Track track =
|
||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
sectorAddress <= trk.TrackEndSector);
|
||||
|
||||
if(track.TrackSequence == 0)
|
||||
@@ -159,7 +159,7 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
|
||||
if(trackStream == null)
|
||||
{
|
||||
@@ -201,7 +201,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
Track track =
|
||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
sectorAddress <= trk.TrackEndSector);
|
||||
|
||||
if(track.TrackSequence == 0)
|
||||
@@ -211,7 +211,7 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
|
||||
if(trackStream == null)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
Track track =
|
||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
sectorAddress <= trk.TrackEndSector);
|
||||
|
||||
if(track.TrackSequence == 0)
|
||||
@@ -270,7 +270,7 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
|
||||
if(trackStream == null)
|
||||
{
|
||||
@@ -305,7 +305,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
Track track =
|
||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
sectorAddress <= trk.TrackEndSector);
|
||||
|
||||
if(track.TrackSequence == 0)
|
||||
@@ -315,7 +315,7 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
FileStream trackStream = writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
FileStream trackStream = _writingStreams.FirstOrDefault(kvp => kvp.Key == track.TrackSequence).Value;
|
||||
|
||||
if(trackStream == null)
|
||||
{
|
||||
@@ -364,42 +364,42 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
if(writingTracks != null &&
|
||||
writingStreams != null)
|
||||
foreach(FileStream oldTrack in writingStreams.Select(t => t.Value).Distinct())
|
||||
if(_writingTracks != null &&
|
||||
_writingStreams != null)
|
||||
foreach(FileStream oldTrack in _writingStreams.Select(t => t.Value).Distinct())
|
||||
oldTrack.Close();
|
||||
|
||||
ulong currentOffset = 0;
|
||||
writingTracks = new List<Track>();
|
||||
_writingTracks = new List<Track>();
|
||||
|
||||
foreach(Track track in tracks.OrderBy(t => t.TrackSequence))
|
||||
{
|
||||
Track newTrack = track;
|
||||
|
||||
newTrack.TrackFile = separateTracksWriting ? writingBaseName + $"_track{track.TrackSequence:D2}.bin"
|
||||
: writingBaseName + ".bin";
|
||||
newTrack.TrackFile = _separateTracksWriting ? _writingBaseName + $"_track{track.TrackSequence:D2}.bin"
|
||||
: _writingBaseName + ".bin";
|
||||
|
||||
newTrack.TrackFileOffset = separateTracksWriting ? 0 : currentOffset;
|
||||
writingTracks.Add(newTrack);
|
||||
newTrack.TrackFileOffset = _separateTracksWriting ? 0 : currentOffset;
|
||||
_writingTracks.Add(newTrack);
|
||||
|
||||
currentOffset += (ulong)newTrack.TrackRawBytesPerSector *
|
||||
((newTrack.TrackEndSector - newTrack.TrackStartSector) + 1);
|
||||
}
|
||||
|
||||
writingStreams = new Dictionary<uint, FileStream>();
|
||||
_writingStreams = new Dictionary<uint, FileStream>();
|
||||
|
||||
if(separateTracksWriting)
|
||||
foreach(Track track in writingTracks)
|
||||
writingStreams.Add(track.TrackSequence,
|
||||
if(_separateTracksWriting)
|
||||
foreach(Track track in _writingTracks)
|
||||
_writingStreams.Add(track.TrackSequence,
|
||||
new FileStream(track.TrackFile, FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
||||
FileShare.None));
|
||||
else
|
||||
{
|
||||
var jointstream = new FileStream(writingBaseName + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
||||
var jointStream = new FileStream(_writingBaseName + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite,
|
||||
FileShare.None);
|
||||
|
||||
foreach(Track track in writingTracks)
|
||||
writingStreams.Add(track.TrackSequence, jointstream);
|
||||
foreach(Track track in _writingTracks)
|
||||
_writingStreams.Add(track.TrackSequence, jointStream);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -414,91 +414,118 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
if(separateTracksWriting)
|
||||
foreach(FileStream writingStream in writingStreams.Values)
|
||||
if(_separateTracksWriting)
|
||||
foreach(FileStream writingStream in _writingStreams.Values)
|
||||
{
|
||||
writingStream.Flush();
|
||||
writingStream.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
writingStreams.First().Value.Flush();
|
||||
writingStreams.First().Value.Close();
|
||||
_writingStreams.First().Value.Flush();
|
||||
_writingStreams.First().Value.Close();
|
||||
}
|
||||
|
||||
int currentSession = 0;
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(discimage.Comment))
|
||||
if(!string.IsNullOrWhiteSpace(_discImage.Comment))
|
||||
{
|
||||
string[] commentLines = discimage.Comment.Split(new[]
|
||||
string[] commentLines = _discImage.Comment.Split(new[]
|
||||
{
|
||||
'\n'
|
||||
}, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach(string line in commentLines)
|
||||
descriptorStream.WriteLine("REM {0}", line);
|
||||
_descriptorStream.WriteLine("REM {0}", line);
|
||||
}
|
||||
|
||||
descriptorStream.WriteLine("REM ORIGINAL MEDIA-TYPE: {0}", MediaTypeToCdrwinType(imageInfo.MediaType));
|
||||
_descriptorStream.WriteLine("REM ORIGINAL MEDIA-TYPE: {0}", MediaTypeToCdrwinType(_imageInfo.MediaType));
|
||||
|
||||
if(!string.IsNullOrEmpty(discimage.Cdtextfile))
|
||||
descriptorStream.WriteLine("CDTEXTFILE \"{0}\"", Path.GetFileName(discimage.Cdtextfile));
|
||||
_descriptorStream.WriteLine("REM METADATA DIC MEDIA-TYPE: {0}", _imageInfo.MediaType);
|
||||
|
||||
if(!string.IsNullOrEmpty(discimage.Title))
|
||||
descriptorStream.WriteLine("TITLE {0}", discimage.Title);
|
||||
if(!string.IsNullOrEmpty(_imageInfo.Application))
|
||||
{
|
||||
_descriptorStream.WriteLine("REM Ripping Tool: {0}", _imageInfo.Application);
|
||||
|
||||
if(!string.IsNullOrEmpty(discimage.Mcn))
|
||||
descriptorStream.WriteLine("CATALOG {0}", discimage.Mcn);
|
||||
if(!string.IsNullOrEmpty(_imageInfo.ApplicationVersion))
|
||||
_descriptorStream.WriteLine("REM Ripping Tool Version: {0}", _imageInfo.ApplicationVersion);
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(discimage.Barcode))
|
||||
descriptorStream.WriteLine("UPC_EAN {0}", discimage.Barcode);
|
||||
if(DumpHardware != null)
|
||||
{
|
||||
foreach(var dumpData in from dump in DumpHardware from extent in dump.Extents.OrderBy(e => e.Start)
|
||||
select new
|
||||
{
|
||||
dump.Manufacturer, dump.Model, dump.Firmware, dump.Serial,
|
||||
Application = dump.Software.Name,
|
||||
ApplicationVersion = dump.Software.Version, dump.Software.OperatingSystem,
|
||||
extent.Start, extent.End
|
||||
})
|
||||
{
|
||||
_descriptorStream.
|
||||
WriteLine($"REM METADATA DUMP EXTENT: {dumpData.Application} | {dumpData.ApplicationVersion} | {dumpData.OperatingSystem} | {dumpData.Manufacturer} | {dumpData.Model} | {dumpData.Firmware} | {dumpData.Serial} | {dumpData.Start}:{dumpData.End}");
|
||||
}
|
||||
}
|
||||
|
||||
if(!separateTracksWriting)
|
||||
descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(writingStreams.First().Value.Name));
|
||||
if(!string.IsNullOrEmpty(_discImage.CdTextFile))
|
||||
_descriptorStream.WriteLine("CDTEXTFILE \"{0}\"", Path.GetFileName(_discImage.CdTextFile));
|
||||
|
||||
foreach(Track track in writingTracks)
|
||||
if(!string.IsNullOrEmpty(_discImage.Title))
|
||||
_descriptorStream.WriteLine("TITLE {0}", _discImage.Title);
|
||||
|
||||
if(!string.IsNullOrEmpty(_discImage.Mcn))
|
||||
_descriptorStream.WriteLine("CATALOG {0}", _discImage.Mcn);
|
||||
|
||||
if(!string.IsNullOrEmpty(_discImage.Barcode))
|
||||
_descriptorStream.WriteLine("UPC_EAN {0}", _discImage.Barcode);
|
||||
|
||||
if(!_separateTracksWriting)
|
||||
_descriptorStream.WriteLine("FILE \"{0}\" BINARY",
|
||||
Path.GetFileName(_writingStreams.First().Value.Name));
|
||||
|
||||
foreach(Track track in _writingTracks)
|
||||
{
|
||||
if(track.TrackSession > currentSession)
|
||||
descriptorStream.WriteLine("REM SESSION {0}", ++currentSession);
|
||||
_descriptorStream.WriteLine("REM SESSION {0}", ++currentSession);
|
||||
|
||||
if(separateTracksWriting)
|
||||
descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(track.TrackFile));
|
||||
if(_separateTracksWriting)
|
||||
_descriptorStream.WriteLine("FILE \"{0}\" BINARY", Path.GetFileName(track.TrackFile));
|
||||
|
||||
(byte minute, byte second, byte frame) msf = LbaToMsf(track.TrackStartSector);
|
||||
descriptorStream.WriteLine(" TRACK {0:D2} {1}", track.TrackSequence, GetTrackMode(track));
|
||||
_descriptorStream.WriteLine(" TRACK {0:D2} {1}", track.TrackSequence, GetTrackMode(track));
|
||||
|
||||
if(trackFlags.TryGetValue((byte)track.TrackSequence, out byte flagsByte))
|
||||
if(_trackFlags.TryGetValue((byte)track.TrackSequence, out byte flagsByte))
|
||||
if(flagsByte != 0 &&
|
||||
flagsByte != (byte)CdFlags.DataTrack)
|
||||
{
|
||||
var flags = (CdFlags)flagsByte;
|
||||
|
||||
descriptorStream.WriteLine(" FLAGS{0}{1}{2}",
|
||||
_descriptorStream.WriteLine(" FLAGS{0}{1}{2}",
|
||||
flags.HasFlag(CdFlags.CopyPermitted) ? " DCP" : "",
|
||||
flags.HasFlag(CdFlags.FourChannel) ? " 4CH" : "",
|
||||
flags.HasFlag(CdFlags.PreEmphasis) ? " PRE" : "");
|
||||
}
|
||||
|
||||
if(trackIsrcs.TryGetValue((byte)track.TrackSequence, out string isrc))
|
||||
descriptorStream.WriteLine(" ISRC {0}", isrc);
|
||||
if(_trackIsrcs.TryGetValue((byte)track.TrackSequence, out string isrc))
|
||||
_descriptorStream.WriteLine(" ISRC {0}", isrc);
|
||||
|
||||
if(track.TrackPregap > 0)
|
||||
{
|
||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 0, msf.minute, msf.second,
|
||||
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 0, msf.minute, msf.second,
|
||||
msf.frame);
|
||||
|
||||
msf = LbaToMsf(track.TrackStartSector + track.TrackPregap);
|
||||
|
||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||
msf.frame);
|
||||
}
|
||||
else
|
||||
descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||
_descriptorStream.WriteLine(" INDEX {0:D2} {1:D2}:{2:D2}:{3:D2}", 1, msf.minute, msf.second,
|
||||
msf.frame);
|
||||
}
|
||||
|
||||
descriptorStream.Flush();
|
||||
descriptorStream.Close();
|
||||
_descriptorStream.Flush();
|
||||
_descriptorStream.Close();
|
||||
|
||||
IsWriting = false;
|
||||
ErrorMessage = "";
|
||||
@@ -523,7 +550,7 @@ namespace DiscImageChef.DiscImages
|
||||
}
|
||||
|
||||
Track track =
|
||||
writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
_writingTracks.FirstOrDefault(trk => sectorAddress >= trk.TrackStartSector &&
|
||||
sectorAddress <= trk.TrackEndSector);
|
||||
|
||||
if(track.TrackSequence == 0)
|
||||
@@ -544,14 +571,14 @@ namespace DiscImageChef.DiscImages
|
||||
return false;
|
||||
}
|
||||
|
||||
trackFlags.Add((byte)track.TrackSequence, data[0]);
|
||||
_trackFlags.Add((byte)track.TrackSequence, data[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
case SectorTagType.CdTrackIsrc:
|
||||
{
|
||||
if(data != null)
|
||||
trackIsrcs.Add((byte)track.TrackSequence, Encoding.UTF8.GetString(data));
|
||||
_trackIsrcs.Add((byte)track.TrackSequence, Encoding.UTF8.GetString(data));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -565,15 +592,22 @@ namespace DiscImageChef.DiscImages
|
||||
public bool WriteSectorsTag(byte[] data, ulong sectorAddress, uint length, SectorTagType tag) =>
|
||||
WriteSectorTag(data, sectorAddress, tag);
|
||||
|
||||
public bool SetDumpHardware(List<DumpHardwareType> dumpHardware) => false;
|
||||
public bool SetDumpHardware(List<DumpHardwareType> dumpHardware)
|
||||
{
|
||||
DumpHardware = dumpHardware;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetCicmMetadata(CICMMetadataType metadata) => false;
|
||||
|
||||
public bool SetMetadata(ImageInfo metadata)
|
||||
{
|
||||
discimage.Barcode = metadata.MediaBarcode;
|
||||
discimage.Comment = metadata.Comments;
|
||||
discimage.Title = metadata.MediaTitle;
|
||||
_discImage.Barcode = metadata.MediaBarcode;
|
||||
_discImage.Comment = metadata.Comments;
|
||||
_discImage.Title = metadata.MediaTitle;
|
||||
_imageInfo.Application = metadata.Application;
|
||||
_imageInfo.ApplicationVersion = metadata.ApplicationVersion;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -186,11 +186,20 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATAPI/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ATIP/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BANDAI/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDRE/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDREDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=BDROM/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=bitsetting/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Bluray/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cartstatus/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDA/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDDB/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDMRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDRWIN/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdtext/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTEXTFILE/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=CDTV/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cdrom/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=certance/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -198,12 +207,25 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=checksums/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cicm/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Claunia/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cuesheet/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DDCD/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Deinterleave/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dicremote/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Drive_0027s/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPMRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPMRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPR/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDPVR/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdr/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=dvdram/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDROM/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=DVDVR/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=ecsd/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=eeprom/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=EVPD/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -211,9 +233,16 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=getconfiguration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvd/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=hddvdr/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRAM/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDROM/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRW/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=HDDVDRWDL/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hldtst/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=iomega/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=isobuster/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=isrc/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Isrcs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Kreon/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastrmd/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=lastsequence/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -242,6 +271,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Plextor/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pmin/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Portillo/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Postgap/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Powe/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregap/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pregaps/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -257,6 +287,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Reiser/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=remapanchor/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=reportdensitysupport/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SCMS/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SDHCI/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Secu/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=spamsum/@EntryIndexedValue">True</s:Boolean>
|
||||
@@ -264,6 +295,7 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subpages/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannel/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subchannels/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Trurip/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=umounting/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=undecoded/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Vari/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
Reference in New Issue
Block a user