1- using System . IO ;
1+ using System . IO ;
22using System . IO . Compression ;
3+ using ICSharpCode . SharpZipLib . Zip . Compression ;
4+ using ICSharpCode . SharpZipLib . Zip . Compression . Streams ;
35
46namespace FreeMote
57{
@@ -53,11 +55,23 @@ public static byte[] Compress(Stream input, bool fast = false)
5355 using var ms = new MemoryStream ( ) ;
5456 ms . WriteByte ( 0x78 ) ;
5557 ms . WriteByte ( ( byte ) ( fast ? 0x9C : 0xDA ) ) ;
56- using ( DeflateStream deflateStream =
57- new DeflateStream ( ms , Consts . ForceCompressionLevel != null ? Consts . ForceCompressionLevel . Value :
58- fast ? CompressionLevel . Fastest : CompressionLevel . Optimal ) )
58+ if ( UseSharpZipLib ( fast ) )
5959 {
60- input . CopyTo ( deflateStream ) ;
60+ var deflaterLevel = GetDeflaterLevel ( fast ) ;
61+ var deflater = new Deflater ( deflaterLevel , true ) ;
62+ using ( var deflateStream = new DeflaterOutputStream ( ms , deflater ) )
63+ {
64+ deflateStream . IsStreamOwner = false ;
65+ input . CopyTo ( deflateStream ) ;
66+ deflateStream . Finish ( ) ;
67+ }
68+ }
69+ else
70+ {
71+ using ( DeflateStream deflateStream = new DeflateStream ( ms , GetSystemCompressionLevel ( fast ) , true ) )
72+ {
73+ input . CopyTo ( deflateStream ) ;
74+ }
6175 }
6276
6377 //input.Dispose();
@@ -81,17 +95,70 @@ public static MemoryStream CompressToStream(Stream input, bool fast = false)
8195 MemoryStream ms = new MemoryStream ( ) ;
8296 ms . WriteByte ( 0x78 ) ;
8397 ms . WriteByte ( ( byte ) ( fast ? 0x9C : 0xDA ) ) ;
84- using ( DeflateStream deflateStream =
85- new DeflateStream ( ms ,
86- Consts . ForceCompressionLevel != null ? Consts . ForceCompressionLevel . Value :
87- fast ? CompressionLevel . Fastest : CompressionLevel . Optimal , true ) )
98+ if ( UseSharpZipLib ( fast ) )
99+ {
100+ var deflaterLevel = GetDeflaterLevel ( fast ) ;
101+ var deflater = new Deflater ( deflaterLevel , true ) ;
102+ using ( var deflateStream = new DeflaterOutputStream ( ms , deflater ) )
103+ {
104+ deflateStream . IsStreamOwner = false ;
105+ input . CopyTo ( deflateStream ) ;
106+ deflateStream . Finish ( ) ;
107+ }
108+ }
109+ else
88110 {
89- input . CopyTo ( deflateStream ) ;
111+ using ( DeflateStream deflateStream = new DeflateStream ( ms , GetSystemCompressionLevel ( fast ) , true ) )
112+ {
113+ input . CopyTo ( deflateStream ) ;
114+ }
90115 }
91116
92117 //input.Dispose(); //DO NOT dispose
93118 ms . Position = 0 ;
94119 return ms ;
95120 }
121+
122+ private static int GetDeflaterLevel ( bool fast )
123+ {
124+ if ( Consts . ForceCompressionLevel != null )
125+ {
126+ switch ( Consts . ForceCompressionLevel . Value )
127+ {
128+ case CompressionLevel . NoCompression :
129+ return Deflater . NO_COMPRESSION ;
130+ case CompressionLevel . Fastest :
131+ return Deflater . BEST_SPEED ;
132+ case CompressionLevel . Optimal :
133+ return Deflater . BEST_COMPRESSION ;
134+ default :
135+ return fast ? Deflater . BEST_SPEED : Deflater . BEST_COMPRESSION ;
136+ }
137+ }
138+
139+ // MDF body in real games usually uses max deflate level (0xDA).
140+ return fast ? Deflater . BEST_SPEED : Deflater . BEST_COMPRESSION ;
141+ }
142+
143+ private static CompressionLevel GetSystemCompressionLevel ( bool fast )
144+ {
145+ if ( Consts . ForceCompressionLevel != null )
146+ {
147+ return Consts . ForceCompressionLevel . Value ;
148+ }
149+
150+ return fast ? CompressionLevel . Fastest : CompressionLevel . Optimal ;
151+ }
152+
153+ private static bool UseSharpZipLib ( bool fast )
154+ {
155+ if ( fast )
156+ {
157+ return false ;
158+ }
159+
160+ // Only use SharpZipLib in optimize mode, so normal mode keeps .NET Deflate speed.
161+ return Consts . OptimizeMode ;
162+ }
96163 }
97164}
0 commit comments