diff --git a/Aaru.Images/AaruFormat/Constants.cs b/Aaru.Images/AaruFormat/Constants.cs
index 778b575cd..c02c0a54c 100644
--- a/Aaru.Images/AaruFormat/Constants.cs
+++ b/Aaru.Images/AaruFormat/Constants.cs
@@ -42,7 +42,9 @@ namespace Aaru.DiscImages
/// Image format version. A change in this number indicates an incompatible change to the format that prevents
/// older implementations from reading it correctly, if at all.
///
- const byte AARUFMT_VERSION = 1;
+ const byte AARUFMT_VERSION_V1 = 1;
+ /// Adds new index format with 64-bit entries counter
+ const byte AARUFMT_VERSION = 2;
/// Maximum read cache size, 256MiB.
const uint MAX_CACHE_SIZE = 256 * 1024 * 1024;
/// Size in bytes of LZMA properties.
diff --git a/Aaru.Images/AaruFormat/Enums.cs b/Aaru.Images/AaruFormat/Enums.cs
index d6599c0ab..ec5c23cc3 100644
--- a/Aaru.Images/AaruFormat/Enums.cs
+++ b/Aaru.Images/AaruFormat/Enums.cs
@@ -218,9 +218,11 @@ namespace Aaru.DiscImages
/// Block containing data
DataBlock = 0x4B4C4244,
/// Block containing a deduplication table
- DeDuplicationTable = 0X2A544444,
+ DeDuplicationTable = 0x2A544444,
/// Block containing the index
- Index = 0X58444E49,
+ Index = 0x58444E49,
+ /// Block containing the index
+ Index2 = 0x32584449,
/// Block containing logical geometry
GeometryBlock = 0x4D4F4547,
/// Block containing metadata
diff --git a/Aaru.Images/AaruFormat/Read.cs b/Aaru.Images/AaruFormat/Read.cs
index e601802d2..c9256640c 100644
--- a/Aaru.Images/AaruFormat/Read.cs
+++ b/Aaru.Images/AaruFormat/Read.cs
@@ -86,28 +86,62 @@ namespace Aaru.DiscImages
imageStream.Read(structureBytes, 0, structureBytes.Length);
IndexHeader idxHeader = Marshal.SpanToStructureLittleEndian(structureBytes);
- if(idxHeader.identifier != BlockType.Index)
+ if(idxHeader.identifier != BlockType.Index &&
+ idxHeader.identifier != BlockType.Index2)
throw new FeatureUnsupportedImageException("Index not found!");
- AaruConsole.DebugWriteLine("Aaru Format plugin", "Index at {0} contains {1} entries", header.indexOffset,
- idxHeader.entries);
-
- AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes", GC.GetTotalMemory(false));
-
- // Fill in-memory index
- index = new List();
-
- for(ushort i = 0; i < idxHeader.entries; i++)
+ if(idxHeader.identifier == BlockType.Index2)
{
- structureBytes = new byte[Marshal.SizeOf()];
+ imageStream.Position = (long)header.indexOffset;
+ structureBytes = new byte[Marshal.SizeOf()];
imageStream.Read(structureBytes, 0, structureBytes.Length);
- IndexEntry entry = Marshal.SpanToStructureLittleEndian(structureBytes);
+ IndexHeader2 idxHeader2 = Marshal.SpanToStructureLittleEndian(structureBytes);
- AaruConsole.DebugWriteLine("Aaru Format plugin",
- "Block type {0} with data type {1} is indexed to be at {2}", entry.blockType,
- entry.dataType, entry.offset);
+ AaruConsole.DebugWriteLine("Aaru Format plugin", "Index at {0} contains {1} entries",
+ header.indexOffset, idxHeader2.entries);
- index.Add(entry);
+ AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes",
+ GC.GetTotalMemory(false));
+
+ // Fill in-memory index
+ index = new List();
+
+ for(ulong i = 0; i < idxHeader2.entries; i++)
+ {
+ structureBytes = new byte[Marshal.SizeOf()];
+ imageStream.Read(structureBytes, 0, structureBytes.Length);
+ IndexEntry entry = Marshal.SpanToStructureLittleEndian(structureBytes);
+
+ AaruConsole.DebugWriteLine("Aaru Format plugin",
+ "Block type {0} with data type {1} is indexed to be at {2}",
+ entry.blockType, entry.dataType, entry.offset);
+
+ index.Add(entry);
+ }
+ }
+ else
+ {
+ AaruConsole.DebugWriteLine("Aaru Format plugin", "Index at {0} contains {1} entries",
+ header.indexOffset, idxHeader.entries);
+
+ AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes",
+ GC.GetTotalMemory(false));
+
+ // Fill in-memory index
+ index = new List();
+
+ for(ushort i = 0; i < idxHeader.entries; i++)
+ {
+ structureBytes = new byte[Marshal.SizeOf()];
+ imageStream.Read(structureBytes, 0, structureBytes.Length);
+ IndexEntry entry = Marshal.SpanToStructureLittleEndian(structureBytes);
+
+ AaruConsole.DebugWriteLine("Aaru Format plugin",
+ "Block type {0} with data type {1} is indexed to be at {2}",
+ entry.blockType, entry.dataType, entry.offset);
+
+ index.Add(entry);
+ }
}
AaruConsole.DebugWriteLine("Aaru Format plugin", "Memory snapshot: {0} bytes", GC.GetTotalMemory(false));
diff --git a/Aaru.Images/AaruFormat/Structs.cs b/Aaru.Images/AaruFormat/Structs.cs
index c3caf7fa6..59e9487f0 100644
--- a/Aaru.Images/AaruFormat/Structs.cs
+++ b/Aaru.Images/AaruFormat/Structs.cs
@@ -101,6 +101,18 @@ namespace Aaru.DiscImages
public ulong crc64;
}
+ /// Header for the index, followed by entries
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct IndexHeader2
+ {
+ /// Identifier,
+ public BlockType identifier;
+ /// How many entries follow this header
+ public ulong entries;
+ /// CRC64-ECMA of the index
+ public ulong crc64;
+ }
+
/// Index entry
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IndexEntry
diff --git a/Aaru.Images/AaruFormat/Write.cs b/Aaru.Images/AaruFormat/Write.cs
index 0cdabd0d9..dd7a628d5 100644
--- a/Aaru.Images/AaruFormat/Write.cs
+++ b/Aaru.Images/AaruFormat/Write.cs
@@ -270,7 +270,7 @@ namespace Aaru.DiscImages
}
header.application = "Aaru";
- header.imageMajorVersion = AARUFMT_VERSION;
+ header.imageMajorVersion = AARUFMT_VERSION_V1;
header.imageMinorVersion = 0;
header.applicationMajorVersion = (byte)typeof(AaruFormat).Assembly.GetName().Version.Major;
header.applicationMinorVersion = (byte)typeof(AaruFormat).Assembly.GetName().Version.Minor;
@@ -3357,15 +3357,36 @@ namespace Aaru.DiscImages
Crc64Context.Data(blockStream.ToArray(), out byte[] idxCrc);
- var idxHeader = new IndexHeader
+ if(index.Count > ushort.MaxValue)
{
- identifier = BlockType.Index, entries = (ushort)index.Count, crc64 = BitConverter.ToUInt64(idxCrc, 0)
- };
+ header.imageMajorVersion = AARUFMT_VERSION;
+
+ var idxHeader = new IndexHeader2
+ {
+ identifier = BlockType.Index2, entries = (ulong)index.Count,
+ crc64 = BitConverter.ToUInt64(idxCrc, 0)
+ };
+
+ // Write index header to disk
+ structureBytes = new byte[Marshal.SizeOf()];
+ MemoryMarshal.Write(structureBytes, ref idxHeader);
+ imageStream.Write(structureBytes, 0, structureBytes.Length);
+ }
+ else
+ {
+ var idxHeader = new IndexHeader
+ {
+ identifier = BlockType.Index, entries = (ushort)index.Count,
+ crc64 = BitConverter.ToUInt64(idxCrc, 0)
+ };
+
+ // Write index header to disk
+ structureBytes = new byte[Marshal.SizeOf()];
+ MemoryMarshal.Write(structureBytes, ref idxHeader);
+ imageStream.Write(structureBytes, 0, structureBytes.Length);
+ }
// Write index to disk
- structureBytes = new byte[Marshal.SizeOf()];
- MemoryMarshal.Write(structureBytes, ref idxHeader);
- imageStream.Write(structureBytes, 0, structureBytes.Length);
imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length);
blockStream.Close();
blockStream = null;