public override System.IO.Stream Open()
{
var reader = Map.OpenPage(Id.Page);
reader.BaseStream.Position = Id.Offset;
ResourceType type;
int id, compressedSize, uncompressedSize;
CompressionMethod compressionMethod;
int compressionCode;
switch (Id.Version) {
case ResourceMapVersion.Sci0:
id = reader.ReadUInt16();
compressedSize = reader.ReadUInt16() - 4;
uncompressedSize = reader.ReadUInt16();
compressionCode = reader.ReadUInt16();
if (id != CombinedIndex)
throw new Exception("Non-matching index.");
switch (compressionCode) {
case 0: compressionMethod = CompressionMethod.None; break;
case 1: compressionMethod = CompressionMethod.Lzw; break;
case 2: compressionMethod = CompressionMethod.Huffman; break;
default: throw new NotSupportedException("Compression mode " + compressionCode + " for engine " + Map.EngineVersion + " is not supported.");
}
break;
case ResourceMapVersion.Sci1:
type = (ResourceType)reader.ReadByte();
id = reader.ReadUInt16();
compressedSize = reader.ReadUInt16();
uncompressedSize = reader.ReadUInt16();
compressionCode = reader.ReadUInt16();
if(id != CombinedIndex)
throw new Exception("Non-matching index.");
if (type != (Id.Type | ResourceType.Sci1Mask))
throw new InvalidDataException("Incorrect type.");
switch (compressionCode) {
case 0: compressionMethod = CompressionMethod.None; break;
case 1: compressionMethod = CompressionMethod.Lzw; break;
case 2: compressionMethod = CompressionMethod.Comp3; break;
case 18:
case 19:
case 20:
compressionMethod = CompressionMethod.DclImplode;
break;
default: throw new NotSupportedException("Compression code " + compressionCode + " for engine " + Id.Version + " is not supported.");
}
break;
case ResourceMapVersion.Sci2:
type = (ResourceType)reader.ReadByte();
id = reader.ReadUInt16();
compressedSize = reader.ReadInt32();
uncompressedSize = reader.ReadInt32();
compressionCode = reader.ReadUInt16();
if (id != CombinedIndex)
throw new InvalidDataException("Non-matching index.");
if (type != Id.FullType)
throw new InvalidDataException(string.Format("Incorrect type found in the resource data; {0} was expected but {1} was found.", Id.FullType, type));
switch (compressionCode) {
case 32: compressionMethod = CompressionMethod.Lzs; break;
default: throw new NotSupportedException(string.Format("Compression code " + compressionCode + " for engine " + Id.Version + " is not supported (Page file=\"{0}\", Offset={1:X}h).", Map.GetPagePath(Id.Page), reader.BaseStream.Position));
}
break;
default:
throw new NotImplementedException("Operation not implemented for version " + Id.Version);
}
byte[] data = ResourceDecompressor.Decompress(reader.BaseStream, compressedSize, uncompressedSize, compressionMethod);
return new MemoryStream(data, false);
}