mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
Fix map chunk decompressing with Mono.
This commit is contained in:
parent
ac3b1b0571
commit
8898d0722b
8 changed files with 1531 additions and 18 deletions
|
@ -124,6 +124,10 @@
|
|||
<Compile Include="Commands\Command.cs" />
|
||||
<Compile Include="Commands\DefaultCommands.cs" />
|
||||
<Compile Include="GraphicsAPI\VertexFormats.cs" />
|
||||
<Compile Include="Ionic.Zlib\DeflateStream.cs" />
|
||||
<Compile Include="Ionic.Zlib\Inflate.cs" />
|
||||
<Compile Include="Ionic.Zlib\InfTree.cs" />
|
||||
<Compile Include="Ionic.Zlib\ZlibCodec.cs" />
|
||||
<Compile Include="Map\ChunkMeshBuilder.cs" />
|
||||
<Compile Include="Map\ChunkMeshBuilderTex2Col4.cs" />
|
||||
<Compile Include="Map\Map.cs" />
|
||||
|
@ -212,6 +216,7 @@
|
|||
<Folder Include="Blocks" />
|
||||
<Folder Include="GraphicsAPI" />
|
||||
<Folder Include="Entities" />
|
||||
<Folder Include="Ionic.Zlib" />
|
||||
<Folder Include="Map" />
|
||||
<Folder Include="Game" />
|
||||
<Folder Include="Model" />
|
||||
|
|
75
Ionic.Zlib/DeflateStream.cs
Normal file
75
Ionic.Zlib/DeflateStream.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Originally copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
|
||||
// All rights reserved.
|
||||
// See license.txt, section Ionic.Zlib license
|
||||
#if __MonoCS__
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Ionic.Zlib {
|
||||
|
||||
internal class DeflateStream {
|
||||
|
||||
ZlibCodec z;
|
||||
bool _leaveOpen;
|
||||
byte[] workBuffer;
|
||||
Stream _stream;
|
||||
|
||||
public DeflateStream( Stream stream, bool leaveOpen ) {
|
||||
_stream = stream;
|
||||
_leaveOpen = leaveOpen;
|
||||
workBuffer = new byte[16384]; // TODO: 1024 bytes?
|
||||
z = new ZlibCodec();
|
||||
}
|
||||
|
||||
public void Close() {
|
||||
z.EndInflate();
|
||||
z = null;
|
||||
|
||||
if( !_leaveOpen )
|
||||
_stream.Close();
|
||||
_stream = null;
|
||||
}
|
||||
|
||||
public int Read( byte[] buffer, int offset, int count ) {
|
||||
// According to MS documentation, any implementation of the IO.Stream.Read function must:
|
||||
// (a) throw an exception if offset & count reference an invalid part of the buffer,
|
||||
// or if count < 0, or if buffer is null
|
||||
// (b) return 0 only upon EOF, or if count = 0
|
||||
// (c) if not EOF, then return at least 1 byte, up to <count> bytes
|
||||
|
||||
if( count == 0 ) return 0;
|
||||
int rc = 0;
|
||||
|
||||
// set up the output of the deflate/inflate codec:
|
||||
z.OutputBuffer = buffer;
|
||||
z.NextOut = offset;
|
||||
z.AvailableBytesOut = count;
|
||||
z.InputBuffer = workBuffer;
|
||||
bool endOfInput = false;
|
||||
|
||||
do {
|
||||
// need data in _workingBuffer in order to deflate/inflate. Here, we check if we have any.
|
||||
if( z.AvailableBytesIn == 0 && !endOfInput ) {
|
||||
// No data available, so try to Read data from the captive stream.
|
||||
z.NextIn = 0;
|
||||
z.AvailableBytesIn = _stream.Read(workBuffer, 0, workBuffer.Length);
|
||||
if( z.AvailableBytesIn == 0 )
|
||||
endOfInput = true;
|
||||
}
|
||||
rc = z.Inflate();
|
||||
|
||||
if (endOfInput && rc == RCode.BufferError)
|
||||
return 0;
|
||||
|
||||
if (rc != RCode.Okay && rc != RCode.StreamEnd)
|
||||
throw new InvalidDataException( "inflating: rc=" + rc );
|
||||
|
||||
if ((endOfInput || rc == RCode.StreamEnd) && z.AvailableBytesOut == count)
|
||||
break; // nothing more to read
|
||||
} while( z.AvailableBytesOut > 0 && !endOfInput && rc == RCode.Okay );
|
||||
|
||||
return count - z.AvailableBytesOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
296
Ionic.Zlib/InfTree.cs
Normal file
296
Ionic.Zlib/InfTree.cs
Normal file
|
@ -0,0 +1,296 @@
|
|||
// Originally copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
|
||||
// All rights reserved.
|
||||
// See license.txt, section Ionic.Zlib license
|
||||
#if __MonoCS__
|
||||
using System;
|
||||
namespace Ionic.Zlib {
|
||||
|
||||
sealed class InfTree {
|
||||
|
||||
const int MANY = 1440;
|
||||
|
||||
static readonly int[] fixed_tl = {96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,
|
||||
0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,
|
||||
14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255};
|
||||
|
||||
static readonly int[] fixed_td = {80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577};
|
||||
|
||||
// Tables for deflate from PKZIP's appnote.txt.
|
||||
static readonly int[] cplens = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
|
||||
// see note #13 above about 258
|
||||
static readonly int[] cplext = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112};
|
||||
|
||||
static readonly int[] cpdist = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
|
||||
|
||||
static readonly int[] cpdext = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
|
||||
|
||||
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
|
||||
const int BMAX = 15; // maximum bit length of any code
|
||||
|
||||
int hn = 0; // hufts used in space
|
||||
int[] v = null; // work area for huft_build
|
||||
int[] c = new int[BMAX + 1]; // bit length count table
|
||||
int r0 = 0, r1 = 0, r2 = 0; // table entry for structure assignment
|
||||
int[] tableStack = new int[BMAX]; // table stack
|
||||
int[] x = new int[BMAX + 1]; // bit offsets, then code stack
|
||||
|
||||
int BuildTree(int[] b, int bindex, int n, int s, int[] d, int[] e, ref int t, ref int m, int[] hp) {
|
||||
// Given a list of code lengths and a maximum table size, make a set of
|
||||
// tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
|
||||
// if the given code set is incomplete (the tables are still built in this
|
||||
// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
|
||||
// lengths), or Z_MEM_ERROR if not enough memory.
|
||||
|
||||
int f; // i repeats in table every f entries
|
||||
int i; // counter, current code
|
||||
int j; // counter
|
||||
int p = 0; // pointer into c[], b[], or v[]
|
||||
int y; // number of dummy codes added
|
||||
|
||||
|
||||
// Generate counts for each bit length
|
||||
i = n;
|
||||
do {
|
||||
c[b[bindex + p]]++;
|
||||
p++;
|
||||
i--; // assume all entries <= BMAX
|
||||
} while (i != 0);
|
||||
|
||||
if (c[0] == n) {
|
||||
// null input--all zero length codes
|
||||
t = -1;
|
||||
m = 0;
|
||||
return RCode.Okay;
|
||||
}
|
||||
|
||||
// Find minimum and maximum length, bound *m by those
|
||||
int bitsPerTable = m; // bits per table (returned in m)
|
||||
for (j = 1; j <= BMAX; j++)
|
||||
if (c[j] != 0)
|
||||
break;
|
||||
|
||||
int curCodeBits = j; // number of bits in current code (starting at minimum code length)
|
||||
if (bitsPerTable < curCodeBits) {
|
||||
bitsPerTable = curCodeBits;
|
||||
}
|
||||
|
||||
for (i = BMAX; i != 0; i--) {
|
||||
if (c[i] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
int maxCodeLen = i; // maximum code length
|
||||
if (bitsPerTable > maxCodeLen) {
|
||||
bitsPerTable = maxCodeLen;
|
||||
}
|
||||
m = bitsPerTable;
|
||||
|
||||
// Adjust last length count to fill out codes, if needed
|
||||
for (y = 1 << j; j < i; j++, y <<= 1) {
|
||||
if ((y -= c[j]) < 0) {
|
||||
return RCode.DataError;
|
||||
}
|
||||
}
|
||||
if ((y -= c[i]) < 0) {
|
||||
return RCode.DataError;
|
||||
}
|
||||
c[i] += y;
|
||||
|
||||
// Generate starting offsets into the value table for each length
|
||||
x[1] = j = 0;
|
||||
p = 1;
|
||||
int xIndex = 2; // pointer into x
|
||||
while (--i != 0) {
|
||||
// note that i == g from above
|
||||
x[xIndex++] = (j += c[p]);
|
||||
p++;
|
||||
}
|
||||
|
||||
// Make a table of values in order of bit lengths
|
||||
i = 0;
|
||||
p = 0;
|
||||
do {
|
||||
if ((j = b[bindex + p]) != 0) {
|
||||
v[x[j]++] = i;
|
||||
}
|
||||
p++;
|
||||
} while (++i < n);
|
||||
n = x[maxCodeLen]; // set n to length of v
|
||||
|
||||
// Generate the Huffman codes and for each, make the table entries
|
||||
x[0] = i = 0; // first Huffman code is zero
|
||||
p = 0; // grab values in bit order
|
||||
int h = -1; // table level, no tables yet so level is -1
|
||||
int w = -bitsPerTable; // bits before this table == (l * h), bits decoded == (l * h)
|
||||
tableStack[0] = 0; // just to keep compilers happy
|
||||
int q = 0; // points to current table
|
||||
int z = 0; // number of entries in current table
|
||||
|
||||
// go through the bit lengths (k already is bits in shortest code)
|
||||
for (; curCodeBits <= maxCodeLen; curCodeBits++)
|
||||
{
|
||||
int a = c[curCodeBits]; // counter for codes of length k
|
||||
while (a-- != 0)
|
||||
{
|
||||
// here i is the Huffman code of length k bits for value *p
|
||||
// make tables up to required level
|
||||
while (curCodeBits > w + bitsPerTable)
|
||||
{
|
||||
h++;
|
||||
w += bitsPerTable; // previous table always l bits
|
||||
// compute minimum size table less than or equal to l bits
|
||||
z = maxCodeLen - w;
|
||||
z = (z > bitsPerTable)?bitsPerTable:z; // table size upper limit
|
||||
if ((f = 1 << (j = curCodeBits - w)) > a + 1)
|
||||
{
|
||||
// try a k-w bit table
|
||||
// too few codes for k-w bit table
|
||||
f -= (a + 1); // deduct codes from patterns left
|
||||
xIndex = curCodeBits;
|
||||
if (j < z)
|
||||
{
|
||||
while (++j < z)
|
||||
{
|
||||
// try smaller tables up to z bits
|
||||
if ((f <<= 1) <= c[++xIndex])
|
||||
break; // enough codes to use up j bits
|
||||
f -= c[xIndex]; // else deduct codes from patterns
|
||||
}
|
||||
}
|
||||
}
|
||||
z = 1 << j; // table entries for j-bit table
|
||||
|
||||
// allocate new table
|
||||
if (hn + z > MANY) {
|
||||
return RCode.DataError; // overflow of MANY
|
||||
}
|
||||
tableStack[h] = q = hn; // DEBUG
|
||||
hn += z;
|
||||
|
||||
// connect to last table, if there is one
|
||||
if (h != 0) {
|
||||
x[h] = i; // save pattern for backing up
|
||||
r0 = (sbyte) j; // bits in this table
|
||||
r1 = (sbyte) bitsPerTable; // bits to dump before this table
|
||||
j = URShift(i, (w - bitsPerTable));
|
||||
r2 = (q - tableStack[h - 1] - j); // offset to this table
|
||||
|
||||
int dstIndex = (tableStack[h - 1] + j) * 3; // connect to last table
|
||||
hp[dstIndex++] = r0;
|
||||
hp[dstIndex++] = r1;
|
||||
hp[dstIndex++] = r2;
|
||||
} else {
|
||||
t = q; // first table is returned result
|
||||
}
|
||||
}
|
||||
|
||||
// set up table entry in r
|
||||
r1 = (sbyte) (curCodeBits - w);
|
||||
if (p >= n) {
|
||||
r0 = 128 + 64; // out of values--invalid code
|
||||
} else if (v[p] < s) {
|
||||
r0 = (sbyte) (v[p] < 256 ? 0: 32 + 64); // 256 is end-of-block
|
||||
r2 = v[p++]; // simple code is just the value
|
||||
} else {
|
||||
r0 = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists
|
||||
r2 = d[v[p++] - s];
|
||||
}
|
||||
|
||||
// fill code-like entries with r
|
||||
f = 1 << (curCodeBits - w);
|
||||
for (j = URShift(i, w); j < z; j += f) {
|
||||
int dstIndex = (q + j) * 3;
|
||||
hp[dstIndex++] = r0;
|
||||
hp[dstIndex++] = r1;
|
||||
hp[dstIndex++] = r2;
|
||||
}
|
||||
|
||||
// backwards increment the k-bit code i
|
||||
for (j = 1 << (curCodeBits - 1); (i & j) != 0; j = URShift(j, 1)) {
|
||||
i ^= j;
|
||||
}
|
||||
i ^= j;
|
||||
|
||||
// backup over finished tables
|
||||
int mask = (1 << w) - 1;
|
||||
while ((i & mask) != x[h]) {
|
||||
h--; // don't need to update q
|
||||
w -= bitsPerTable;
|
||||
mask = (1 << w) - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return Z_BUF_ERROR if we were given an incomplete table
|
||||
return y != 0 && maxCodeLen != 1 ? RCode.BufferError : RCode.Okay;
|
||||
}
|
||||
|
||||
internal void InflateTreeBits(int[] c, ref int bb, ref int tb, int[] hp, ZlibCodec z) {
|
||||
ResetWorkArea( 19 );
|
||||
hn = 0;
|
||||
int result = BuildTree(c, 0, 19, 19, null, null, ref tb, ref bb, hp);
|
||||
|
||||
if (result == RCode.DataError) {
|
||||
throw new InvalidOperationException( "oversubscribed dynamic bit lengths tree" );
|
||||
} else if (result == RCode.BufferError || bb == 0) {
|
||||
throw new InvalidOperationException( "incomplete dynamic bit lengths tree" );
|
||||
}
|
||||
}
|
||||
|
||||
internal void InflateTreesDynamic(int nl, int nd, int[] c, ref int bl, ref int bd,
|
||||
ref int tl, ref int td, int[] hp, ZlibCodec z) {
|
||||
// build literal/length tree
|
||||
ResetWorkArea( 288 );
|
||||
hn = 0;
|
||||
int result = BuildTree(c, 0, nl, 257, cplens, cplext, ref tl, ref bl, hp);
|
||||
if (result != RCode.Okay || bl == 0) {
|
||||
string message = null;
|
||||
if (result == RCode.DataError) {
|
||||
message = "oversubscribed literal/length tree";
|
||||
} else {
|
||||
message = "incomplete literal/length tree";
|
||||
}
|
||||
throw new InvalidOperationException( "Unable to inflate dynamic tree: " + message );
|
||||
}
|
||||
|
||||
// build distance tree
|
||||
ResetWorkArea( 288 );
|
||||
result = BuildTree(c, nl, nd, 0, cpdist, cpdext, ref td, ref bd, hp);
|
||||
|
||||
if (result != RCode.Okay || (bd == 0 && nl > 257)) {
|
||||
string message = null;
|
||||
if (result == RCode.DataError) {
|
||||
message = "oversubscribed distance tree";
|
||||
} else if (result == RCode.BufferError) {
|
||||
message = "incomplete distance tree";
|
||||
} else {
|
||||
message = "empty distance tree with lengths";
|
||||
}
|
||||
throw new InvalidOperationException( "Unable to inflate dynamic tree: " + message );
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InflateTreesFixed( out int bl, out int bd, out int[] tl, out int[] td ) {
|
||||
bl = 9;
|
||||
bd = 5;
|
||||
tl = fixed_tl;
|
||||
td = fixed_td;
|
||||
}
|
||||
|
||||
void ResetWorkArea( int vsize ) {
|
||||
if( v == null || v.Length < vsize ) {
|
||||
v = new int[vsize];
|
||||
}
|
||||
Array.Clear(v, 0, vsize);
|
||||
Array.Clear(c, 0, BMAX + 1);
|
||||
r0 = 0; r1 = 0; r2 = 0;
|
||||
Array.Clear(tableStack, 0, BMAX);
|
||||
Array.Clear(x, 0, BMAX + 1);
|
||||
}
|
||||
|
||||
static int URShift( int value, int bits ) {
|
||||
return (int)( (uint)value >> bits );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
981
Ionic.Zlib/Inflate.cs
Normal file
981
Ionic.Zlib/Inflate.cs
Normal file
|
@ -0,0 +1,981 @@
|
|||
// Originally copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
|
||||
// All rights reserved.
|
||||
// See license.txt, section Ionic.Zlib license
|
||||
#if __MonoCS__
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Ionic.Zlib
|
||||
{
|
||||
sealed class InflateBlocks
|
||||
{
|
||||
const int MANY = 1440;
|
||||
|
||||
// Table for deflate from PKZIP's appnote.txt.
|
||||
static readonly int[] border = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
|
||||
enum InflateBlockMode {
|
||||
TYPE = 0, // get type bits (3, including end bit)
|
||||
LENS = 1, // get lengths for stored
|
||||
STORED = 2, // processing stored block
|
||||
TABLE = 3, // get table lengths
|
||||
BTREE = 4, // get bit lengths tree for a dynamic block
|
||||
DTREE = 5, // get length, distance trees for a dynamic block
|
||||
CODES = 6, // processing fixed or dynamic block
|
||||
DRY = 7, // output remaining window bytes
|
||||
DONE = 8, // finished last block, done
|
||||
}
|
||||
|
||||
InflateBlockMode mode; // current inflate_block mode
|
||||
|
||||
int left; // if STORED, bytes left to copy
|
||||
|
||||
int table; // table lengths (14 bits)
|
||||
int index; // index into blens (or border)
|
||||
int[] blens; // bit lengths of codes
|
||||
int bb; // bit length tree depth
|
||||
int tb; // bit length decoding tree
|
||||
|
||||
InflateCodes codes = new InflateCodes(); // if CODES, current state
|
||||
int last; // true if this block is the last block
|
||||
internal ZlibCodec codec; // pointer back to this zlib stream
|
||||
|
||||
// mode independent information
|
||||
internal int bitk; // bits in bit buffer
|
||||
internal int bitb; // bit buffer
|
||||
internal int[] hufts; // single malloc for tree space
|
||||
internal byte[] window; // sliding window
|
||||
internal int end; // one byte after sliding window
|
||||
internal int readAt; // window read pointer
|
||||
internal int writeAt; // window write pointer
|
||||
|
||||
InfTree inftree = new InfTree();
|
||||
|
||||
internal InflateBlocks(ZlibCodec codec, int w) {
|
||||
this.codec = codec;
|
||||
hufts = new int[MANY * 3];
|
||||
window = new byte[w];
|
||||
end = w;
|
||||
mode = InflateBlockMode.TYPE;
|
||||
Reset();
|
||||
}
|
||||
|
||||
internal void Reset() {
|
||||
mode = InflateBlockMode.TYPE;
|
||||
bitk = 0;
|
||||
bitb = 0;
|
||||
readAt = writeAt = 0;
|
||||
}
|
||||
|
||||
internal int Process(int r) {
|
||||
int t; // temporary storage
|
||||
int nextIn = codec.NextIn; // input data pointer
|
||||
int availIn = codec.AvailableBytesIn; // bytes available there
|
||||
int bits = bitb; // bit buffer
|
||||
int bitsNum = bitk; // bits in bit buffer
|
||||
int q = writeAt; // output window write pointer
|
||||
int m = q < readAt ? readAt - q - 1 : end - q; // bytes to end of window or read pointer
|
||||
|
||||
// process input based on current state
|
||||
while (true)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case InflateBlockMode.TYPE:
|
||||
while( bitsNum < 3 ) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
last = bits & 0x1;
|
||||
switch( ( bits & 0x7 ) >> 1 ) {
|
||||
case 0: // stored
|
||||
bits >>= 3; bitsNum -= 3;
|
||||
t = bitsNum & 7; // go to byte boundary
|
||||
bits >>= t; bitsNum -= t;
|
||||
mode = InflateBlockMode.LENS; // get length of stored block
|
||||
break;
|
||||
|
||||
case 1: // fixed
|
||||
int bl, bd;
|
||||
int[] tl, td;
|
||||
InfTree.InflateTreesFixed(out bl, out bd, out tl, out td);
|
||||
codes.Init(bl, bd, tl, 0, td, 0);
|
||||
bits >>= 3; bitsNum -= 3;
|
||||
mode = InflateBlockMode.CODES;
|
||||
break;
|
||||
|
||||
case 2: // dynamic
|
||||
bits >>= 3; bitsNum -= 3;
|
||||
mode = InflateBlockMode.TABLE;
|
||||
break;
|
||||
|
||||
case 3: // illegal
|
||||
throw new InvalidDataException( "invalid block type" );
|
||||
} break;
|
||||
|
||||
case InflateBlockMode.LENS:
|
||||
while( bitsNum < 32 ) {
|
||||
if( availIn != 0 ) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
if ( ( ( ~bits >> 16 ) & 0xffff ) != ( bits & 0xffff ) ) {
|
||||
throw new InvalidDataException( "invalid stored block lengths" );
|
||||
}
|
||||
left = bits & 0xffff;
|
||||
bits = bitsNum = 0; // dump bits
|
||||
mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
|
||||
break;
|
||||
|
||||
case InflateBlockMode.STORED:
|
||||
if( availIn == 0 ) {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
if( m == 0 ) {
|
||||
if( q == end && readAt != 0 ) {
|
||||
q = 0;
|
||||
m = q < readAt ? readAt - q - 1 : end - q;
|
||||
}
|
||||
if( m == 0 ) {
|
||||
writeAt = q;
|
||||
r = Flush(r);
|
||||
q = writeAt;
|
||||
m = q < readAt ? readAt - q - 1 : end - q;
|
||||
|
||||
if( q == end && readAt != 0 ) {
|
||||
q = 0;
|
||||
m = q < readAt ? readAt - q - 1 : end - q;
|
||||
}
|
||||
if( m == 0 ) {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
r = RCode.Okay;
|
||||
|
||||
t = left;
|
||||
if (t > availIn)
|
||||
t = availIn;
|
||||
if (t > m)
|
||||
t = m;
|
||||
Array.Copy(codec.InputBuffer, nextIn, window, q, t);
|
||||
nextIn += t; availIn -= t;
|
||||
q += t; m -= t;
|
||||
if ((left -= t) != 0)
|
||||
break;
|
||||
mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
|
||||
break;
|
||||
|
||||
case InflateBlockMode.TABLE:
|
||||
while (bitsNum < 14) {
|
||||
if( availIn != 0 ) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
table = t = (bits & 0x3fff);
|
||||
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
|
||||
throw new InvalidDataException( "too many length or distance symbols" );
|
||||
}
|
||||
|
||||
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
|
||||
if (blens == null || blens.Length < t) {
|
||||
blens = new int[t];
|
||||
} else {
|
||||
Array.Clear(blens, 0, t);
|
||||
}
|
||||
|
||||
bits >>= 14;
|
||||
bitsNum -= 14;
|
||||
|
||||
index = 0;
|
||||
mode = InflateBlockMode.BTREE;
|
||||
goto case InflateBlockMode.BTREE;
|
||||
|
||||
case InflateBlockMode.BTREE:
|
||||
while (index < 4 + (table >> 10)) {
|
||||
while( bitsNum < 3 ) {
|
||||
if( availIn != 0 ) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
blens[border[index++]] = bits & 7;
|
||||
bits >>= 3; bitsNum -= 3;
|
||||
}
|
||||
|
||||
while (index < 19) {
|
||||
blens[border[index++]] = 0;
|
||||
}
|
||||
|
||||
bb = 7;
|
||||
inftree.InflateTreeBits(blens, ref bb, ref tb, hufts, codec);
|
||||
index = 0;
|
||||
mode = InflateBlockMode.DTREE;
|
||||
goto case InflateBlockMode.DTREE;
|
||||
|
||||
case InflateBlockMode.DTREE:
|
||||
while (true) {
|
||||
t = table;
|
||||
if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
|
||||
break;
|
||||
}
|
||||
t = bb;
|
||||
|
||||
while (bitsNum < t) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
t = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 1];
|
||||
int c = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 2];
|
||||
|
||||
if( c < 16 ) {
|
||||
bits >>= t; bitsNum -= t;
|
||||
blens[index++] = c;
|
||||
} else {
|
||||
// c == 16..18
|
||||
int i = c == 18 ? 7 : c - 14;
|
||||
int j = c == 18 ? 11 : 3;
|
||||
|
||||
while( bitsNum < ( t + i ) ) {
|
||||
if( availIn != 0 ) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
|
||||
availIn--;
|
||||
bits |= codec.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
bits >>= t; bitsNum -= t;
|
||||
j += (bits & Constants.InflateMask[i]);
|
||||
bits >>= i; bitsNum -= i;
|
||||
|
||||
i = index;
|
||||
if (i + j > 258 + (table & 0x1f) + ((table >> 5) & 0x1f) || (c == 16 && i < 1)) {
|
||||
throw new InvalidDataException( "invalid bit length repeat" );
|
||||
}
|
||||
|
||||
c = (c == 16) ? blens[i-1] : 0;
|
||||
do {
|
||||
blens[i++] = c;
|
||||
} while (--j != 0);
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
tb = -1;
|
||||
{
|
||||
int bl = 9; // must be <= 9 for lookahead assumptions
|
||||
int bd = 6; // must be <= 9 for lookahead assumptions
|
||||
int tl = 0;
|
||||
int td = 0;
|
||||
inftree.InflateTreesDynamic(257 + (table & 0x1f), 1 + ((table >> 5) & 0x1f), blens,
|
||||
ref bl, ref bd, ref tl, ref td, hufts, codec);
|
||||
codes.Init(bl, bd, hufts, tl, hufts, td);
|
||||
}
|
||||
mode = InflateBlockMode.CODES;
|
||||
goto case InflateBlockMode.CODES;
|
||||
|
||||
case InflateBlockMode.CODES:
|
||||
UpdateState( bits, bitsNum, availIn, nextIn, q );
|
||||
|
||||
r = codes.Process(this, r);
|
||||
if( r != RCode.StreamEnd ) {
|
||||
return Flush(r);
|
||||
}
|
||||
|
||||
r = RCode.Okay;
|
||||
nextIn = codec.NextIn;
|
||||
availIn = codec.AvailableBytesIn;
|
||||
bits = bitb;
|
||||
bitsNum = bitk;
|
||||
q = writeAt;
|
||||
m = q < readAt ? readAt - q - 1 : end - q;
|
||||
|
||||
if (last == 0)
|
||||
{
|
||||
mode = InflateBlockMode.TYPE;
|
||||
break;
|
||||
}
|
||||
mode = InflateBlockMode.DRY;
|
||||
goto case InflateBlockMode.DRY;
|
||||
|
||||
case InflateBlockMode.DRY:
|
||||
writeAt = q;
|
||||
r = Flush(r);
|
||||
q = writeAt;
|
||||
m = q < readAt ? readAt - q - 1 : end - q;
|
||||
if (readAt != writeAt) {
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
mode = InflateBlockMode.DONE;
|
||||
goto case InflateBlockMode.DONE;
|
||||
|
||||
case InflateBlockMode.DONE:
|
||||
return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
|
||||
default:
|
||||
throw new InvalidOperationException( "Invalid inflate block mode: " + mode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal int RanOutOfInput( int bits, int bitsNum, int availIn, int nextIn, int q, int r ) {
|
||||
bitb = bits;
|
||||
bitk = bitsNum;
|
||||
codec.AvailableBytesIn = availIn;
|
||||
codec.NextIn = nextIn;
|
||||
writeAt = q;
|
||||
return Flush(r);
|
||||
}
|
||||
|
||||
internal void UpdateState( int bits, int bitsNum, int availIn, int nextIn, int q ) {
|
||||
bitb = bits;
|
||||
bitk = bitsNum;
|
||||
codec.AvailableBytesIn = availIn;
|
||||
codec.NextIn = nextIn;
|
||||
writeAt = q;
|
||||
}
|
||||
|
||||
internal void Free() {
|
||||
Reset();
|
||||
window = null;
|
||||
hufts = null;
|
||||
}
|
||||
|
||||
// copy as much as possible from the sliding window to the output area
|
||||
internal int Flush( int r ) {
|
||||
for( int pass = 0; pass < 2; pass++ ) {
|
||||
int nBytes = pass == 0 ?
|
||||
// compute number of bytes to copy as far as end of window
|
||||
((readAt <= writeAt ? writeAt : end) - readAt) :
|
||||
// compute bytes to copy
|
||||
writeAt - readAt;
|
||||
|
||||
// workitem 8870
|
||||
if (nBytes == 0) {
|
||||
if (r == RCode.BufferError)
|
||||
r = RCode.Okay;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (nBytes > codec.AvailableBytesOut)
|
||||
nBytes = codec.AvailableBytesOut;
|
||||
|
||||
if (nBytes != 0 && r == RCode.BufferError)
|
||||
r = RCode.Okay;
|
||||
|
||||
// update counters
|
||||
codec.AvailableBytesOut -= nBytes;
|
||||
|
||||
// copy as far as end of window
|
||||
Array.Copy(window, readAt, codec.OutputBuffer, codec.NextOut, nBytes);
|
||||
codec.NextOut += nBytes;
|
||||
readAt += nBytes;
|
||||
|
||||
// see if more to copy at beginning of window
|
||||
if (readAt == end && pass == 0) {
|
||||
// wrap pointers
|
||||
readAt = 0;
|
||||
if (writeAt == end)
|
||||
writeAt = 0;
|
||||
} else {
|
||||
pass++;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Constants {
|
||||
// And'ing with mask[n] masks the lower n bits
|
||||
internal static readonly int[] InflateMask = {
|
||||
0x00000000, 0x00000001, 0x00000003, 0x00000007,
|
||||
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
|
||||
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
|
||||
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff };
|
||||
}
|
||||
|
||||
|
||||
sealed class InflateCodes
|
||||
{
|
||||
// waiting for "i:"=input, "o:"=output, "x:"=nothing
|
||||
const int START = 0; // x: set up for LEN
|
||||
const int LEN = 1; // i: get length/literal/eob next
|
||||
const int LENEXT = 2; // i: getting length extra (have base)
|
||||
const int DIST = 3; // i: get distance next
|
||||
const int DISTEXT = 4; // i: getting distance extra
|
||||
const int COPY = 5; // o: copying bytes in window, waiting for space
|
||||
const int LIT = 6; // o: got literal, waiting for output space
|
||||
const int WASH = 7; // o: got eob, possibly still output waiting
|
||||
const int END = 8; // x: got eob and all data flushed
|
||||
const int BADCODE = 9; // x: got error
|
||||
|
||||
int mode; // current inflate_codes mode
|
||||
|
||||
// mode dependent information
|
||||
int len;
|
||||
|
||||
int[] tree; // pointer into tree
|
||||
int tree_index = 0;
|
||||
int need; // bits needed
|
||||
|
||||
int lit;
|
||||
|
||||
// if EXT or COPY, where and how much
|
||||
int bitsToGet; // bits to get for extra
|
||||
int dist; // distance back to copy from
|
||||
|
||||
byte lbits; // ltree bits decoded per branch
|
||||
byte dbits; // dtree bits decoder per branch
|
||||
int[] ltree; // literal/length/eob tree
|
||||
int ltree_index; // literal/length/eob tree
|
||||
int[] dtree; // distance tree
|
||||
int dtree_index; // distance tree
|
||||
|
||||
internal void Init(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index) {
|
||||
mode = START;
|
||||
lbits = (byte)bl;
|
||||
dbits = (byte)bd;
|
||||
ltree = tl;
|
||||
ltree_index = tl_index;
|
||||
dtree = td;
|
||||
dtree_index = td_index;
|
||||
tree = null;
|
||||
}
|
||||
|
||||
internal int Process(InflateBlocks blocks, int r)
|
||||
{
|
||||
int tindex; // temporary pointer
|
||||
int e; // extra bits or operation
|
||||
|
||||
ZlibCodec z = blocks.codec;
|
||||
int nextIn = z.NextIn;// input data pointer
|
||||
int availIn = z.AvailableBytesIn; // bytes available there
|
||||
int bits = blocks.bitb; // bit buffer
|
||||
int bitsNum = blocks.bitk; // bits in bit buffer
|
||||
int q = blocks.writeAt; // output window write pointer
|
||||
int m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q; // bytes to end of window or read pointer
|
||||
|
||||
// process input and output based on current state
|
||||
while (true)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
// waiting for "i:"=input, "o:"=output, "x:"=nothing
|
||||
case START: // x: set up for LEN
|
||||
if (m >= 258 && availIn >= 10) {
|
||||
blocks.UpdateState( bits, bitsNum, availIn, nextIn, q );
|
||||
r = InflateFast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, blocks, z);
|
||||
|
||||
nextIn = z.NextIn;
|
||||
availIn = z.AvailableBytesIn;
|
||||
bits = blocks.bitb;
|
||||
bitsNum = blocks.bitk;
|
||||
q = blocks.writeAt;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
|
||||
if (r != RCode.Okay)
|
||||
{
|
||||
mode = (r == RCode.StreamEnd) ? WASH : BADCODE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
need = lbits;
|
||||
tree = ltree;
|
||||
tree_index = ltree_index;
|
||||
|
||||
mode = LEN;
|
||||
goto case LEN;
|
||||
|
||||
case LEN: // i: get length/literal/eob next
|
||||
while (bitsNum < need) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
tindex = (tree_index + (bits & Constants.InflateMask[need])) * 3;
|
||||
|
||||
bits >>= (tree[tindex + 1]);
|
||||
bitsNum -= (tree[tindex + 1]);
|
||||
|
||||
e = tree[tindex];
|
||||
|
||||
if (e == 0) {
|
||||
// literal
|
||||
lit = tree[tindex + 2];
|
||||
mode = LIT;
|
||||
break;
|
||||
}
|
||||
if ((e & 16) != 0) {
|
||||
// length
|
||||
bitsToGet = e & 15;
|
||||
len = tree[tindex + 2];
|
||||
mode = LENEXT;
|
||||
break;
|
||||
}
|
||||
if ((e & 64) == 0) {
|
||||
// next table
|
||||
need = e;
|
||||
tree_index = tindex / 3 + tree[tindex + 2];
|
||||
break;
|
||||
}
|
||||
if ((e & 32) != 0) {
|
||||
// end of block
|
||||
mode = WASH;
|
||||
break;
|
||||
}
|
||||
throw new InvalidDataException( "invalid literal/length code" );
|
||||
|
||||
|
||||
case LENEXT: // i: getting length extra (have base)
|
||||
while (bitsNum < bitsToGet) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
len += (bits & Constants.InflateMask[bitsToGet]);
|
||||
|
||||
bits >>= bitsToGet;
|
||||
bitsNum -= bitsToGet;
|
||||
|
||||
need = dbits;
|
||||
tree = dtree;
|
||||
tree_index = dtree_index;
|
||||
mode = DIST;
|
||||
goto case DIST;
|
||||
|
||||
case DIST: // i: get distance next
|
||||
while (bitsNum < need) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
tindex = (tree_index + (bits & Constants.InflateMask[need])) * 3;
|
||||
|
||||
bits >>= tree[tindex + 1];
|
||||
bitsNum -= tree[tindex + 1];
|
||||
|
||||
e = tree[tindex];
|
||||
if ((e & 0x10) != 0) {
|
||||
// distance
|
||||
bitsToGet = e & 15;
|
||||
dist = tree[tindex + 2];
|
||||
mode = DISTEXT;
|
||||
break;
|
||||
}
|
||||
if ((e & 64) == 0) {
|
||||
// next table
|
||||
need = e;
|
||||
tree_index = tindex / 3 + tree[tindex + 2];
|
||||
break;
|
||||
}
|
||||
throw new InvalidDataException( "invalid distance code" );
|
||||
|
||||
|
||||
case DISTEXT: // i: getting distance extra
|
||||
while (bitsNum < bitsToGet) {
|
||||
if (availIn != 0) {
|
||||
r = RCode.Okay;
|
||||
} else {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
dist += (bits & Constants.InflateMask[bitsToGet]);
|
||||
|
||||
bits >>= bitsToGet;
|
||||
bitsNum -= bitsToGet;
|
||||
|
||||
mode = COPY;
|
||||
goto case COPY;
|
||||
|
||||
case COPY: // o: copying bytes in window, waiting for space
|
||||
int f = q - dist; // pointer to copy strings from
|
||||
while (f < 0) {
|
||||
// modulo window size-"while" instead
|
||||
f += blocks.end; // of "if" handles invalid distances
|
||||
}
|
||||
while (len != 0) {
|
||||
if (m == 0) {
|
||||
if (q == blocks.end && blocks.readAt != 0) {
|
||||
q = 0;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
}
|
||||
|
||||
if (m == 0) {
|
||||
blocks.writeAt = q;
|
||||
r = blocks.Flush(r);
|
||||
q = blocks.writeAt;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
|
||||
if (q == blocks.end && blocks.readAt != 0) {
|
||||
q = 0;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
}
|
||||
|
||||
if (m == 0) {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blocks.window[q++] = blocks.window[f++];
|
||||
m--;
|
||||
|
||||
if (f == blocks.end)
|
||||
f = 0;
|
||||
len--;
|
||||
}
|
||||
mode = START;
|
||||
break;
|
||||
|
||||
case LIT: // o: got literal, waiting for output space
|
||||
if (m == 0) {
|
||||
if (q == blocks.end && blocks.readAt != 0) {
|
||||
q = 0;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
}
|
||||
|
||||
if (m == 0) {
|
||||
blocks.writeAt = q;
|
||||
r = blocks.Flush(r);
|
||||
q = blocks.writeAt;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
|
||||
if (q == blocks.end && blocks.readAt != 0)
|
||||
{
|
||||
q = 0;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
}
|
||||
if (m == 0) {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = RCode.Okay;
|
||||
blocks.window[q++] = (byte)lit;
|
||||
m--;
|
||||
mode = START;
|
||||
break;
|
||||
|
||||
case WASH: // o: got eob, possibly more output
|
||||
if (bitsNum > 7)
|
||||
{
|
||||
// return unused byte, if any
|
||||
bitsNum -= 8;
|
||||
availIn++;
|
||||
nextIn--; // can always return one
|
||||
}
|
||||
|
||||
blocks.writeAt = q;
|
||||
r = blocks.Flush(r);
|
||||
q = blocks.writeAt;
|
||||
m = q < blocks.readAt ? blocks.readAt - q - 1 : blocks.end - q;
|
||||
|
||||
if (blocks.readAt != blocks.writeAt) {
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
}
|
||||
mode = END;
|
||||
goto case END;
|
||||
|
||||
case END:
|
||||
r = RCode.StreamEnd;
|
||||
return blocks.RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
|
||||
|
||||
default:
|
||||
throw new InvalidDataException( "Encountered error: " + mode );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called with number of bytes left to write in window at least 258
|
||||
// (the maximum string length) and number of input bytes available
|
||||
// at least ten. The ten bytes are six bytes for the longest length/
|
||||
// distance pair plus four bytes for overloading the bit buffer.
|
||||
internal int InflateFast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InflateBlocks s, ZlibCodec z)
|
||||
{
|
||||
int e; // extra bits or operation
|
||||
int c; // bytes to copy
|
||||
|
||||
int nextIn = z.NextIn; // input data pointer
|
||||
int availIn = z.AvailableBytesIn; // bytes available there
|
||||
int bits = s.bitb; // bit buffer
|
||||
int bitsNum = s.bitk; // bits in bit buffer
|
||||
int q = s.writeAt; // output window write pointer
|
||||
int m = q < s.readAt ? s.readAt - q - 1 : s.end - q; // bytes to end of window or read pointer
|
||||
|
||||
int ml = Constants.InflateMask[bl]; // mask for literal/length tree
|
||||
int md = Constants.InflateMask[bd]; // mask for distance tree
|
||||
|
||||
// do until not enough input or output space for fast loop
|
||||
do {
|
||||
// assume called with m >= 258 && n >= 10
|
||||
// get literal/length code
|
||||
while (bitsNum < 20) {
|
||||
// max bits for literal/length code
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
int t = bits & ml; // temporary pointer
|
||||
int[] tp = tl;// temporary pointer
|
||||
int tp_index = tl_index;// temporary pointer
|
||||
int tp_index_t_3 = (tp_index + t) * 3;
|
||||
|
||||
if ((e = tp[tp_index_t_3]) == 0) {
|
||||
bits >>= tp[tp_index_t_3 + 1];
|
||||
bitsNum -= tp[tp_index_t_3 + 1];
|
||||
|
||||
s.window[q++] = (byte)tp[tp_index_t_3 + 2];
|
||||
m--;
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
bits >>= tp[tp_index_t_3 + 1];
|
||||
bitsNum -= tp[tp_index_t_3 + 1];
|
||||
|
||||
if ((e & 16) != 0) {
|
||||
e &= 15;
|
||||
c = tp[tp_index_t_3 + 2] + (bits & Constants.InflateMask[e]);
|
||||
|
||||
bits >>= e; bitsNum -= e;
|
||||
|
||||
// decode distance base of block to copy
|
||||
while (bitsNum < 15) {
|
||||
// max bits for distance code
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
t = bits & md;
|
||||
tp = td;
|
||||
tp_index = td_index;
|
||||
tp_index_t_3 = (tp_index + t) * 3;
|
||||
e = tp[tp_index_t_3];
|
||||
|
||||
do {
|
||||
bits >>= (tp[tp_index_t_3 + 1]);
|
||||
bitsNum -= (tp[tp_index_t_3 + 1]);
|
||||
|
||||
if ((e & 16) != 0) {
|
||||
// get extra bits to add to distance base
|
||||
e &= 15;
|
||||
while (bitsNum < e) {
|
||||
// get extra bits (up to 13)
|
||||
availIn--;
|
||||
bits |= z.InputBuffer[nextIn++] << bitsNum;
|
||||
bitsNum += 8;
|
||||
}
|
||||
|
||||
int d = tp[tp_index_t_3 + 2] + (bits & Constants.InflateMask[e]); // distance back to copy from
|
||||
bits >>= e; bitsNum -= e;
|
||||
|
||||
// do the copy
|
||||
int r = q - d; // copy source pointer
|
||||
m -= c;
|
||||
if (q >= d) {
|
||||
// offset before dest, just copy
|
||||
if (q - r > 0 && 2 > (q - r)) {
|
||||
s.window[q++] = s.window[r++]; // minimum count is three,
|
||||
s.window[q++] = s.window[r++]; // so unroll loop a little
|
||||
} else {
|
||||
Array.Copy(s.window, r, s.window, q, 2);
|
||||
q += 2; r += 2;
|
||||
}
|
||||
c -= 2;
|
||||
} else {
|
||||
// else offset after destination
|
||||
do {
|
||||
r += s.end; // force pointer in window
|
||||
} while (r < 0); // covers invalid distances
|
||||
e = s.end - r;
|
||||
if (c > e) {
|
||||
// if source crosses,
|
||||
c -= e; // wrapped copy
|
||||
if (q - r > 0 && e > (q - r)) {
|
||||
do {
|
||||
s.window[q++] = s.window[r++];
|
||||
} while (--e != 0);
|
||||
} else {
|
||||
Array.Copy(s.window, r, s.window, q, e);
|
||||
q += e; r += e; e = 0;
|
||||
}
|
||||
r = 0; // copy rest from start of window
|
||||
}
|
||||
}
|
||||
|
||||
// copy all or what's left
|
||||
if( q - r > 0 && c > ( q - r ) ) {
|
||||
do {
|
||||
s.window[q++] = s.window[r++];
|
||||
} while ( --c != 0 );
|
||||
} else {
|
||||
Array.Copy( s.window, r, s.window, q, c );
|
||||
q += c; r += c;
|
||||
c = 0;
|
||||
}
|
||||
break;
|
||||
} else if ( ( e & 64 ) == 0 ) {
|
||||
t += tp[tp_index_t_3 + 2];
|
||||
t += (bits & Constants.InflateMask[e]);
|
||||
tp_index_t_3 = (tp_index + t) * 3;
|
||||
e = tp[tp_index_t_3];
|
||||
} else {
|
||||
throw new InvalidDataException( "invalid distance code" );
|
||||
}
|
||||
} while (true);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ( e & 64 ) == 0 ) {
|
||||
t += tp[tp_index_t_3 + 2];
|
||||
t += (bits & Constants.InflateMask[e]);
|
||||
tp_index_t_3 = (tp_index + t) * 3;
|
||||
if ((e = tp[tp_index_t_3]) == 0)
|
||||
{
|
||||
bits >>= (tp[tp_index_t_3 + 1]); bitsNum -= (tp[tp_index_t_3 + 1]);
|
||||
s.window[q++] = (byte)tp[tp_index_t_3 + 2];
|
||||
m--;
|
||||
break;
|
||||
}
|
||||
} else if ( ( e & 32 ) != 0 ) {
|
||||
c = z.AvailableBytesIn - availIn;
|
||||
c = (bitsNum >> 3) < c ? bitsNum >> 3 : c;
|
||||
availIn += c;
|
||||
nextIn -= c;
|
||||
bitsNum -= (c << 3);
|
||||
|
||||
s.UpdateState( bits, bitsNum, availIn, nextIn, q );
|
||||
return RCode.StreamEnd;
|
||||
} else {
|
||||
throw new InvalidDataException( "invalid literal/length code" );
|
||||
}
|
||||
} while (true);
|
||||
} while (m >= 258 && availIn >= 10);
|
||||
|
||||
// not enough input or output--restore pointers and return
|
||||
c = z.AvailableBytesIn - availIn;
|
||||
c = (bitsNum >> 3) < c ? bitsNum >> 3 : c;
|
||||
availIn += c;
|
||||
nextIn -= c;
|
||||
bitsNum -= (c << 3);
|
||||
|
||||
s.UpdateState( bits, bitsNum, availIn, nextIn, q );
|
||||
return RCode.Okay;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal sealed class InflateManager
|
||||
{
|
||||
bool done = false;
|
||||
ZlibCodec _codec; // pointer back to this zlib stream
|
||||
|
||||
int wbits; // log2(window size) (8..15, defaults to 15)
|
||||
InflateBlocks blocks; // current inflate_blocks state
|
||||
|
||||
internal void Reset() {
|
||||
done = false;
|
||||
blocks.Reset();
|
||||
}
|
||||
|
||||
internal void End() {
|
||||
if (blocks != null)
|
||||
blocks.Free();
|
||||
blocks = null;
|
||||
}
|
||||
|
||||
internal void Initialize( ZlibCodec codec, int w ) {
|
||||
_codec = codec;
|
||||
blocks = null;
|
||||
|
||||
wbits = w;
|
||||
blocks = new InflateBlocks( codec, 1 << w );
|
||||
Reset();
|
||||
}
|
||||
|
||||
internal int Inflate() {
|
||||
if (_codec.InputBuffer == null)
|
||||
throw new InvalidOperationException("InputBuffer is null. ");
|
||||
|
||||
int r = RCode.BufferError;
|
||||
if( !done ) {
|
||||
r = blocks.Process(r);
|
||||
if( r == RCode.DataError ) {
|
||||
throw new InvalidDataException( "Bad state" );
|
||||
}
|
||||
|
||||
if (r != RCode.StreamEnd)
|
||||
return r;
|
||||
|
||||
blocks.Reset();
|
||||
done = true;
|
||||
}
|
||||
return RCode.StreamEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
44
Ionic.Zlib/ZlibCodec.cs
Normal file
44
Ionic.Zlib/ZlibCodec.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Originally copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
|
||||
// All rights reserved.
|
||||
// See license.txt, section Ionic.Zlib license
|
||||
#if __MonoCS__
|
||||
using System;
|
||||
|
||||
namespace Ionic.Zlib {
|
||||
|
||||
public sealed class ZlibCodec {
|
||||
|
||||
public byte[] InputBuffer;
|
||||
public int NextIn;
|
||||
public int AvailableBytesIn;
|
||||
|
||||
public byte[] OutputBuffer;
|
||||
public int NextOut;
|
||||
public int AvailableBytesOut;
|
||||
|
||||
InflateManager istate;
|
||||
|
||||
public ZlibCodec() {
|
||||
istate = new InflateManager();
|
||||
const int windowBits = 15; // 32K LZ77 window (max value 15, min value 8)
|
||||
istate.Initialize( this, windowBits );
|
||||
}
|
||||
|
||||
public int Inflate() {
|
||||
return istate.Inflate();
|
||||
}
|
||||
|
||||
public void EndInflate() {
|
||||
istate.End();
|
||||
istate = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class RCode {
|
||||
public const int Okay = 0;
|
||||
public const int StreamEnd = 1;
|
||||
public const int DataError = -3;
|
||||
public const int BufferError = -5;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -2,10 +2,13 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
#if __MonoCS__
|
||||
using Ionic.Zlib;
|
||||
#else
|
||||
using System.IO.Compression;
|
||||
#endif
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using ClassicalSharp.Network;
|
||||
using OpenTK;
|
||||
|
||||
|
@ -288,7 +291,13 @@ namespace ClassicalSharp {
|
|||
}
|
||||
receivedFirstPosition = false;
|
||||
gzipHeader = new GZipHeaderReader();
|
||||
// Workaround because built in mono stream assumes that the end of stream
|
||||
// has been reached the first time a read call returns 0. (MS.NET doesn't)
|
||||
#if __MonoCS__
|
||||
gzipStream = new DeflateStream( gzippedMap, true );
|
||||
#else
|
||||
gzipStream = new DeflateStream( gzippedMap, CompressionMode.Decompress );
|
||||
#endif
|
||||
mapSizeIndex = 0;
|
||||
mapIndex = 0;
|
||||
receiveStart = DateTime.UtcNow;
|
||||
|
@ -330,7 +339,7 @@ namespace ClassicalSharp {
|
|||
Window.Map.UseRawMap( map, mapWidth, mapHeight, mapLength );
|
||||
Window.RaiseOnNewMapLoaded();
|
||||
map = null;
|
||||
gzipStream.Dispose();
|
||||
gzipStream.Close();
|
||||
if( sendWomId && !sentWomId ) {
|
||||
SendChat( "/womid WoMClient-2.0.6" );
|
||||
sentWomId = true;
|
||||
|
|
|
@ -226,11 +226,12 @@ namespace ClassicalSharp {
|
|||
Graphics.AlphaBlending = true;
|
||||
Graphics.Texturing = true;
|
||||
Graphics.ColourWrite = true;
|
||||
//Graphics.DepthWrite = false; TODO: test if this makes a difference.
|
||||
for( int batch = 0; batch < _1Dcount; batch++ ) {
|
||||
Graphics.Bind2DTexture( texIds[batch] );
|
||||
RenderTranslucentBatch( batch );
|
||||
}
|
||||
|
||||
//Graphics.DepthWrite = true;
|
||||
Graphics.AlphaTest = false;
|
||||
Graphics.AlphaBlending = false;
|
||||
Graphics.Texturing = false;
|
||||
|
|
114
license.txt
114
license.txt
|
@ -36,7 +36,9 @@ Unless otherwise noted, you may use any and all code examples provided herein in
|
|||
|
||||
|
||||
|
||||
ClassicalSharp uses the OpenTK library. The license of OpenTK is reproduced below:
|
||||
OpenTK license
|
||||
===============
|
||||
|
||||
The Open Toolkit library license
|
||||
|
||||
Copyright (c) 2006 - 2010 The Open Toolkit library.
|
||||
|
@ -48,11 +50,6 @@ The above copyright notice and this permission notice shall be included in all c
|
|||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
|
||||
|
||||
Third parties
|
||||
|
||||
|
||||
OpenTK.Platform.Windows and OpenTK.Platform.X11 include portions of the Mono class library. These portions are covered by the following license:
|
||||
|
||||
Copyright (c) 2004 Novell, Inc.
|
||||
|
@ -62,3 +59,108 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
Ionic.Zlib license
|
||||
==================
|
||||
Microsoft Public License (Ms-PL)
|
||||
|
||||
This license governs use of the accompanying software, the DotNetZip library ("the software"). If you use the software, you accept this license. If you do not accept the license, do not use the software.
|
||||
|
||||
1. Definitions
|
||||
|
||||
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
|
||||
|
||||
A "contribution" is the original software, or any additions or changes to the software.
|
||||
|
||||
A "contributor" is any person that distributes its contribution under this license.
|
||||
|
||||
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
|
||||
|
||||
2. Grant of Rights
|
||||
|
||||
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
|
||||
|
||||
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
|
||||
|
||||
3. Conditions and Limitations
|
||||
|
||||
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
|
||||
|
||||
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
|
||||
|
||||
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
|
||||
|
||||
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
|
||||
|
||||
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
|
||||
|
||||
The following licenses govern use of the accompanying software, the
|
||||
DotNetZip library ("the software"). If you use the software, you accept
|
||||
these licenses. If you do not accept the license, do not use the software.
|
||||
|
||||
The managed ZLIB code included in Ionic.Zlib.dll and Ionic.Zip.dll is
|
||||
modified code, based on jzlib.
|
||||
|
||||
|
||||
|
||||
The following notice applies to jzlib:
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
jzlib is based on zlib-1.1.3.
|
||||
|
||||
The following notice applies to zlib:
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
|
||||
|
||||
The ZLIB software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Jean-loup Gailly jloup@gzip.org
|
||||
Mark Adler madler@alumni.caltech.edu
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue