For DiscImageChef format, add options for dictionary and in-memory ddt sizes.

This commit is contained in:
2018-01-25 00:29:07 +00:00
parent ac211cc8b5
commit 2888aa73ae

View File

@@ -65,6 +65,7 @@
the pointer in the corresponding deduplication table. the pointer in the corresponding deduplication table.
P.S.: Data Position Measurement is doable, as soon as I know how to do it. P.S.: Data Position Measurement is doable, as soon as I know how to do it.
P.S.2: Support for floppy image containg bitslices and/or fluxes will be added soon.
*/ */
using System; using System;
@@ -110,6 +111,7 @@ namespace DiscImageChef.DiscImages
Stream imageStream; Stream imageStream;
List<IndexEntry> index; List<IndexEntry> index;
bool inMemoryDdt; bool inMemoryDdt;
LzmaEncoderProperties lzmaEncoderProperties;
Dictionary<MediaTagType, byte[]> mediaTags; Dictionary<MediaTagType, byte[]> mediaTags;
long outMemoryDdtPosition; long outMemoryDdtPosition;
byte[] sectorPrefix; byte[] sectorPrefix;
@@ -1373,7 +1375,11 @@ namespace DiscImageChef.DiscImages
new[] new[]
{ {
("sectors_per_block", typeof(uint), ("sectors_per_block", typeof(uint),
"How many sectors to store per block (will be rounded to next power of two)") "How many sectors to store per block (will be rounded to next power of two)"),
("dictionary", typeof(uint),
"Size, in bytes, of the LZMA dictionary"),
("max_ddt_size", typeof(uint),
"Maximum size, in mebibytes, for in-memory DDT. If image needs a bigger one, it will be on-disk")
}; };
public IEnumerable<string> KnownExtensions => new[] {".dicf"}; public IEnumerable<string> KnownExtensions => new[] {".dicf"};
public bool IsWriting { get; private set; } public bool IsWriting { get; private set; }
@@ -1384,8 +1390,11 @@ namespace DiscImageChef.DiscImages
uint sectorSize) uint sectorSize)
{ {
uint sectorsPerBlock; uint sectorsPerBlock;
uint dictionary;
uint maxDdtSize;
if(options != null) if(options != null)
{
if(options.TryGetValue("sectors_per_block", out string tmpValue)) if(options.TryGetValue("sectors_per_block", out string tmpValue))
{ {
if(!uint.TryParse(tmpValue, out sectorsPerBlock)) if(!uint.TryParse(tmpValue, out sectorsPerBlock))
@@ -1394,10 +1403,35 @@ namespace DiscImageChef.DiscImages
return false; return false;
} }
} }
else
sectorsPerBlock = 4096;
else sectorsPerBlock = 4096; else sectorsPerBlock = 4096;
if(options.TryGetValue("dictionary", out tmpValue))
{
if(!uint.TryParse(tmpValue, out dictionary))
{
ErrorMessage = "Invalid value for dictionary option";
return false;
}
}
else dictionary = 1 << 25;
if(options.TryGetValue("dictionary", out tmpValue))
{
if(!uint.TryParse(tmpValue, out maxDdtSize))
{
ErrorMessage = "Invalid value for max_ddt_size option";
return false;
}
}
else maxDdtSize = 256;
}
else
{
sectorsPerBlock = 4096;
dictionary = 1 << 25;
maxDdtSize = 256;
}
if(!SupportedMediaTypes.Contains(mediaType)) if(!SupportedMediaTypes.Contains(mediaType))
{ {
ErrorMessage = $"Unsupport media format {mediaType}"; ErrorMessage = $"Unsupport media format {mediaType}";
@@ -1445,8 +1479,7 @@ namespace DiscImageChef.DiscImages
creationTime = DateTime.UtcNow.ToFileTimeUtc() creationTime = DateTime.UtcNow.ToFileTimeUtc()
}; };
// TODO: Settable inMemoryDdt = sectors <= maxDdtSize * 1024 * 1024 / sizeof(ulong);
inMemoryDdt = sectors <= 256 * 1024 * 1024 / sizeof(ulong);
DicConsole.DebugWriteLine("DiscImageChef format plugin", "In memory DDT?: {0}", inMemoryDdt); DicConsole.DebugWriteLine("DiscImageChef format plugin", "In memory DDT?: {0}", inMemoryDdt);
@@ -1493,6 +1526,8 @@ namespace DiscImageChef.DiscImages
trackIsrcs = new Dictionary<byte, string>(); trackIsrcs = new Dictionary<byte, string>();
trackFlags = new Dictionary<byte, byte>(); trackFlags = new Dictionary<byte, byte>();
lzmaEncoderProperties = new LzmaEncoderProperties(true, (int)dictionary, 255);
IsWriting = true; IsWriting = true;
ErrorMessage = null; ErrorMessage = null;
return true; return true;
@@ -1574,7 +1609,7 @@ namespace DiscImageChef.DiscImages
if(blockStream == null) if(blockStream == null)
{ {
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
currentBlockHeader = new BlockHeader currentBlockHeader = new BlockHeader
{ {
identifier = BlockType.DataBlock, identifier = BlockType.DataBlock,
@@ -1933,7 +1968,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
compressedBlockStream.Write(mediaTag.Value, 0, mediaTag.Value.Length); compressedBlockStream.Write(mediaTag.Value, 0, mediaTag.Value.Length);
byte[] lzmaProperties = compressedBlockStream.Properties; byte[] lzmaProperties = compressedBlockStream.Properties;
compressedBlockStream.Close(); compressedBlockStream.Close();
@@ -2017,7 +2052,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
crc64 = new Crc64Context(); crc64 = new Crc64Context();
crc64.Init(); crc64.Init();
for(ulong i = 0; i < (ulong)userDataDdt.LongLength; i++) for(ulong i = 0; i < (ulong)userDataDdt.LongLength; i++)
@@ -2048,8 +2083,9 @@ namespace DiscImageChef.DiscImages
index.Add(idxEntry); index.Add(idxEntry);
} }
if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc && Tracks != null && Tracks.Count > 0) switch(imageInfo.XmlMediaType)
{ {
case XmlMediaType.OpticalDisc when Tracks != null && Tracks.Count > 0:
if(sectorPrefix != null && sectorSuffix != null) if(sectorPrefix != null && sectorSuffix != null)
{ {
idxEntry = new IndexEntry idxEntry = new IndexEntry
@@ -2073,7 +2109,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
compressedBlockStream.Write(sectorPrefix, 0, sectorPrefix.Length); compressedBlockStream.Write(sectorPrefix, 0, sectorPrefix.Length);
byte[] lzmaProperties = compressedBlockStream.Properties; byte[] lzmaProperties = compressedBlockStream.Properties;
compressedBlockStream.Close(); compressedBlockStream.Close();
@@ -2118,7 +2154,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
compressedBlockStream.Write(sectorSuffix, 0, sectorSuffix.Length); compressedBlockStream.Write(sectorSuffix, 0, sectorSuffix.Length);
lzmaProperties = compressedBlockStream.Properties; lzmaProperties = compressedBlockStream.Properties;
compressedBlockStream.Close(); compressedBlockStream.Close();
@@ -2167,7 +2203,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
compressedBlockStream.Write(sectorSubchannel, 0, sectorSubchannel.Length); compressedBlockStream.Write(sectorSubchannel, 0, sectorSubchannel.Length);
byte[] lzmaProperties = compressedBlockStream.Properties; byte[] lzmaProperties = compressedBlockStream.Properties;
compressedBlockStream.Close(); compressedBlockStream.Close();
@@ -2255,8 +2291,9 @@ namespace DiscImageChef.DiscImages
imageStream.Write(structureBytes, 0, structureBytes.Length); imageStream.Write(structureBytes, 0, structureBytes.Length);
imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length); imageStream.Write(blockStream.ToArray(), 0, (int)blockStream.Length);
} }
}
else if(imageInfo.XmlMediaType == XmlMediaType.BlockMedia) break;
case XmlMediaType.BlockMedia:
if(sectorSubchannel != null && if(sectorSubchannel != null &&
(imageInfo.MediaType == MediaType.AppleFileWare || (imageInfo.MediaType == MediaType.AppleFileWare ||
imageInfo.MediaType == MediaType.AppleSonySS || imageInfo.MediaType == MediaType.AppleSonySS ||
@@ -2304,7 +2341,7 @@ namespace DiscImageChef.DiscImages
}; };
blockStream = new MemoryStream(); blockStream = new MemoryStream();
compressedBlockStream = new LzmaStream(new LzmaEncoderProperties(), false, blockStream); compressedBlockStream = new LzmaStream(lzmaEncoderProperties, false, blockStream);
compressedBlockStream.Write(sectorSubchannel, 0, sectorSubchannel.Length); compressedBlockStream.Write(sectorSubchannel, 0, sectorSubchannel.Length);
byte[] lzmaProperties = compressedBlockStream.Properties; byte[] lzmaProperties = compressedBlockStream.Properties;
compressedBlockStream.Close(); compressedBlockStream.Close();
@@ -2330,6 +2367,9 @@ namespace DiscImageChef.DiscImages
blockStream = null; blockStream = null;
} }
break;
}
MetadataBlock metadataBlock = new MetadataBlock(); MetadataBlock metadataBlock = new MetadataBlock();
blockStream = new MemoryStream(); blockStream = new MemoryStream();
blockStream.Write(new byte[Marshal.SizeOf(metadataBlock)], 0, Marshal.SizeOf(metadataBlock)); blockStream.Write(new byte[Marshal.SizeOf(metadataBlock)], 0, Marshal.SizeOf(metadataBlock));