/// <summary>Open the resource data as a stream, decompressing it as necessary.</summary> /// <returns></returns> 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)); }