mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Save Compact Disc track indexes in aaruformat.
This commit is contained in:
@@ -244,7 +244,9 @@ namespace Aaru.DiscImages
|
|||||||
/// <summary>Block containing list of files for a tape image</summary>
|
/// <summary>Block containing list of files for a tape image</summary>
|
||||||
TapeFileBlock = 0x454C4654,
|
TapeFileBlock = 0x454C4654,
|
||||||
/// <summary>Block containing list of partitions for a tape image</summary>
|
/// <summary>Block containing list of partitions for a tape image</summary>
|
||||||
TapePartitionBlock = 0x54425054
|
TapePartitionBlock = 0x54425054,
|
||||||
|
/// <summary>Block containing list of indexes for Compact Disc tracks</summary>
|
||||||
|
CompactDiscIndexesBlock = 0x58494443
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ChecksumAlgorithm : byte
|
enum ChecksumAlgorithm : byte
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ namespace Aaru.DiscImages
|
|||||||
|
|
||||||
bool foundUserDataDdt = false;
|
bool foundUserDataDdt = false;
|
||||||
mediaTags = new Dictionary<MediaTagType, byte[]>();
|
mediaTags = new Dictionary<MediaTagType, byte[]>();
|
||||||
|
List<CompactDiscIndexEntry> compactDiscIndexes = null;
|
||||||
|
|
||||||
foreach(IndexEntry entry in index)
|
foreach(IndexEntry entry in index)
|
||||||
{
|
{
|
||||||
@@ -994,6 +995,59 @@ namespace Aaru.DiscImages
|
|||||||
IsTape = true;
|
IsTape = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Optical disc tracks block
|
||||||
|
case BlockType.CompactDiscIndexesBlock:
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<CompactDiscIndexesHeader>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
|
||||||
|
CompactDiscIndexesHeader indexesHeader =
|
||||||
|
Marshal.SpanToStructureLittleEndian<CompactDiscIndexesHeader>(structureBytes);
|
||||||
|
|
||||||
|
if(indexesHeader.identifier != BlockType.CompactDiscIndexesBlock)
|
||||||
|
{
|
||||||
|
AaruConsole.DebugWriteLine("Aaru Format plugin",
|
||||||
|
"Incorrect identifier for compact disc indexes block at position {0}",
|
||||||
|
entry.offset);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<CompactDiscIndexEntry>() * indexesHeader.entries];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
Crc64Context.Data(structureBytes, out byte[] idsxCrc);
|
||||||
|
|
||||||
|
if(BitConverter.ToUInt64(idsxCrc, 0) != indexesHeader.crc64)
|
||||||
|
{
|
||||||
|
AaruConsole.DebugWriteLine("Aaru Format plugin",
|
||||||
|
"Incorrect CRC found: 0x{0:X16} found, expected 0x{1:X16}, continuing...",
|
||||||
|
BitConverter.ToUInt64(idsxCrc, 0), indexesHeader.crc64);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
imageStream.Position -= structureBytes.Length;
|
||||||
|
|
||||||
|
compactDiscIndexes = new List<CompactDiscIndexEntry>();
|
||||||
|
|
||||||
|
AaruConsole.DebugWriteLine("Aaru Format plugin",
|
||||||
|
"Found {0} compact disc indexes at position {0}",
|
||||||
|
indexesHeader.entries, entry.offset);
|
||||||
|
|
||||||
|
for(ushort i = 0; i < indexesHeader.entries; i++)
|
||||||
|
{
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<CompactDiscIndexEntry>()];
|
||||||
|
imageStream.Read(structureBytes, 0, structureBytes.Length);
|
||||||
|
|
||||||
|
compactDiscIndexes.Add(Marshal.
|
||||||
|
ByteArrayToStructureLittleEndian<CompactDiscIndexEntry
|
||||||
|
>(structureBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes",
|
||||||
|
GC.GetTotalMemory(false));
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1147,6 +1201,20 @@ namespace Aaru.DiscImages
|
|||||||
|
|
||||||
AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes",
|
AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes",
|
||||||
GC.GetTotalMemory(false));
|
GC.GetTotalMemory(false));
|
||||||
|
|
||||||
|
if(compactDiscIndexes != null)
|
||||||
|
{
|
||||||
|
foreach(CompactDiscIndexEntry compactDiscIndex in compactDiscIndexes.
|
||||||
|
OrderBy(i => i.Track).ThenBy(i => i.Index))
|
||||||
|
{
|
||||||
|
Track track = Tracks.FirstOrDefault(t => t.TrackSequence == compactDiscIndex.Track);
|
||||||
|
|
||||||
|
if(track is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
track.Indexes[compactDiscIndex.Index] = compactDiscIndex.Lba;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -380,5 +380,33 @@ namespace Aaru.DiscImages
|
|||||||
/// <summary>Last block, inclusive, of the partition</summary>
|
/// <summary>Last block, inclusive, of the partition</summary>
|
||||||
public ulong LastBlock;
|
public ulong LastBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compact Disc track indexes block, contains a cache of all Compact Disc indexes to not need to interpret
|
||||||
|
/// subchannel
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct CompactDiscIndexesHeader
|
||||||
|
{
|
||||||
|
/// <summary>Identifier, <see cref="BlockType.CompactDiscIndexesBlock" /></summary>
|
||||||
|
public BlockType identifier;
|
||||||
|
/// <summary>How many entries follow this header</summary>
|
||||||
|
public ushort entries;
|
||||||
|
/// <summary>Size of the whole block, not including this header, in bytes</summary>
|
||||||
|
public readonly ulong length;
|
||||||
|
/// <summary>CRC64-ECMA of the block</summary>
|
||||||
|
public ulong crc64;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct CompactDiscIndexEntry
|
||||||
|
{
|
||||||
|
/// <summary>How many entries follow this header</summary>
|
||||||
|
public ushort Track;
|
||||||
|
/// <summary>Size of the whole block, not including this header, in bytes</summary>
|
||||||
|
public ushort Index;
|
||||||
|
/// <summary>CRC64-ECMA of the block</summary>
|
||||||
|
public int Lba;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2928,7 +2928,8 @@ namespace Aaru.DiscImages
|
|||||||
blockStream = null;
|
blockStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<TrackEntry> trackEntries = new List<TrackEntry>();
|
List<TrackEntry> trackEntries = new List<TrackEntry>();
|
||||||
|
List<CompactDiscIndexEntry> compactDiscIndexEntries = new List<CompactDiscIndexEntry>();
|
||||||
|
|
||||||
foreach(Track track in Tracks)
|
foreach(Track track in Tracks)
|
||||||
{
|
{
|
||||||
@@ -2946,6 +2947,21 @@ namespace Aaru.DiscImages
|
|||||||
pregap = (long)track.TrackPregap, session = (byte)track.TrackSession, isrc = isrc,
|
pregap = (long)track.TrackPregap, session = (byte)track.TrackSession, isrc = isrc,
|
||||||
flags = flags
|
flags = flags
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!track.Indexes.ContainsKey(0) &&
|
||||||
|
track.TrackPregap > 0)
|
||||||
|
{
|
||||||
|
track.Indexes[0] = (int)track.TrackStartSector;
|
||||||
|
track.Indexes[1] = (int)(track.TrackStartSector + track.TrackPregap);
|
||||||
|
}
|
||||||
|
else if(!track.Indexes.ContainsKey(0) &&
|
||||||
|
!track.Indexes.ContainsKey(1))
|
||||||
|
track.Indexes[0] = (int)track.TrackStartSector;
|
||||||
|
|
||||||
|
compactDiscIndexEntries.AddRange(track.Indexes.Select(trackIndex => new CompactDiscIndexEntry
|
||||||
|
{
|
||||||
|
Index = trackIndex.Key, Lba = trackIndex.Value, Track = (ushort)track.TrackSequence
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are tracks build the tracks block
|
// If there are tracks build the tracks block
|
||||||
@@ -2995,6 +3011,56 @@ namespace Aaru.DiscImages
|
|||||||
blockStream = null;
|
blockStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are track indexes bigger than 1
|
||||||
|
if(compactDiscIndexEntries.Any(i => i.Index > 1))
|
||||||
|
{
|
||||||
|
blockStream = new NonClosableStream();
|
||||||
|
|
||||||
|
foreach(CompactDiscIndexEntry entry in compactDiscIndexEntries)
|
||||||
|
{
|
||||||
|
structurePointer =
|
||||||
|
System.Runtime.InteropServices.Marshal.AllocHGlobal(Marshal.
|
||||||
|
SizeOf<CompactDiscIndexEntry
|
||||||
|
>());
|
||||||
|
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<CompactDiscIndexEntry>()];
|
||||||
|
System.Runtime.InteropServices.Marshal.StructureToPtr(entry, structurePointer, true);
|
||||||
|
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(structurePointer, structureBytes, 0,
|
||||||
|
structureBytes.Length);
|
||||||
|
|
||||||
|
System.Runtime.InteropServices.Marshal.FreeHGlobal(structurePointer);
|
||||||
|
blockStream.Write(structureBytes, 0, structureBytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
Crc64Context.Data(blockStream.ToArray(), out byte[] cdixCrc);
|
||||||
|
|
||||||
|
var cdixHeader = new CompactDiscIndexesHeader
|
||||||
|
{
|
||||||
|
identifier = BlockType.CompactDiscIndexesBlock,
|
||||||
|
entries = (ushort)compactDiscIndexEntries.Count, crc64 = BitConverter.ToUInt64(cdixCrc, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
AaruConsole.DebugWriteLine("Aaru Format plugin", "Writing compact disc indexes to position {0}",
|
||||||
|
imageStream.Position);
|
||||||
|
|
||||||
|
index.RemoveAll(t => t.blockType == BlockType.CompactDiscIndexesBlock &&
|
||||||
|
t.dataType == DataType.NoData);
|
||||||
|
|
||||||
|
index.Add(new IndexEntry
|
||||||
|
{
|
||||||
|
blockType = BlockType.CompactDiscIndexesBlock, dataType = DataType.NoData,
|
||||||
|
offset = (ulong)imageStream.Position
|
||||||
|
});
|
||||||
|
|
||||||
|
structureBytes = new byte[Marshal.SizeOf<CompactDiscIndexesHeader>()];
|
||||||
|
MemoryMarshal.Write(structureBytes, ref cdixHeader);
|
||||||
|
imageStream.Write(structureBytes, 0, structureBytes.Length);
|
||||||
|
imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length);
|
||||||
|
blockStream.ReallyClose();
|
||||||
|
blockStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case XmlMediaType.BlockMedia:
|
case XmlMediaType.BlockMedia:
|
||||||
if(sectorSubchannel != null &&
|
if(sectorSubchannel != null &&
|
||||||
|
|||||||
Reference in New Issue
Block a user