Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951).
This class compresses and decompresses data according to the Deflate algorithm and optionally, the ZLIB format, as documented in RFC 1950 - ZLIB and RFC 1951 - DEFLATE.
Exemplo n.º 1
0
 internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
 {
     bl[0] = fixed_bl;
     bd[0] = fixed_bd;
     tl[0] = fixed_tl;
     td[0] = fixed_td;
     return Z_OK;
 }
Exemplo n.º 2
0
		private void end()
		{
			if (z == null)
				return;
			//if (_wantCompress)
			//{
			//    _z.EndDeflate();
			//}
			//else
			{
				_z.EndInflate();
			}
			_z = null;
		}
Exemplo n.º 3
0
        internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z)
        {
            int result;

            initWorkArea(19);
            hn[0] = 0;
            result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);

            if (result == Z_DATA_ERROR)
            {
                z.Message = "oversubscribed dynamic bit lengths tree";
            }
            else if (result == Z_BUF_ERROR || bb[0] == 0)
            {
                z.Message = "incomplete dynamic bit lengths tree";
                result = Z_DATA_ERROR;
            }

            return result;
        }
Exemplo n.º 4
0
        internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
        {
            int result;

            // build literal/length tree
            initWorkArea(288);
            hn[0] = 0;
            result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);

            if (result != Z_OK || bl[0] == 0)
            {
                if (result == Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed literal/length tree";
                }
                else if (result != Z_MEM_ERROR)
                {
                    z.Message = "incomplete literal/length tree";
                    result = Z_DATA_ERROR;
                }

                return result;
            }

            // build distance tree
            initWorkArea(288);
            result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);

            if (result != Z_OK || (bd[0] == 0 && nl > 257))
            {
                if (result == Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed distance tree";
                }
                else if (result == Z_BUF_ERROR)
                {
                    z.Message = "incomplete distance tree";
                    result = Z_DATA_ERROR;
                }
                else if (result != Z_MEM_ERROR)
                {
                    z.Message = "empty distance tree with lengths";
                    result = Z_DATA_ERROR;
                }

                return result;
            }

            return Z_OK;
        }
Exemplo n.º 5
0
		internal int Initialize(ZlibCodec codec, int w)
		{
			_codec = codec;
			_codec.Message = null;
			blocks = null;

			// handle undocumented nowrap option (no zlib header or check)
			//nowrap = 0;
			//if (w < 0)
			//{
			//    w = - w;
			//    nowrap = 1;
			//}

			// set window size
			if (w < 8 || w > 15)
			{
				End();
				throw new ZlibException("Bad window size.");

				//return ZlibConstants.Z_STREAM_ERROR;
			}
			wbits = w;

			blocks = new InflateBlocks(codec,
				HandleRfc1950HeaderBytes ? this : null,
				1 << w);

			// reset state
			Reset();
			return ZlibConstants.Z_OK;
		}
Exemplo n.º 6
0
		// Returns true if inflate is currently at the end of a block generated
		// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
		// implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
		// but removes the length bytes of the resulting empty stored block. When
		// decompressing, PPP checks that at the end of input packet, inflate is
		// waiting for these length bytes.
		internal int SyncPoint(ZlibCodec z)
		{
			return blocks.SyncPoint();
		}
Exemplo n.º 7
0
		// 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 t; // temporary pointer
			int[] tp; // temporary pointer
			int tp_index; // temporary pointer
			int e; // extra bits or operation
			int b; // bit buffer
			int k; // bits in bit buffer
			int p; // input data pointer
			int n; // bytes available there
			int q; // output window write pointer
			int m; // bytes to end of window or read pointer
			int ml; // mask for literal/length tree
			int md; // mask for distance tree
			int c; // bytes to copy
			int d; // distance back to copy from
			int r; // copy source pointer

			int tp_index_t_3; // (tp_index+t)*3

			// load input, output, bit values
			p = z.NextIn; n = z.AvailableBytesIn; b = s.bitb; k = s.bitk;
			q = s.write; m = q < s.read ? s.read - q - 1 : s.end - q;

			// initialize masks
			ml = inflate_mask[bl];
			md = inflate_mask[bd];

			// do until not enough input or output space for fast loop
			do
			{
				// assume called with m >= 258 && n >= 10
				// get literal/length code
				while (k < (20))
				{
					// max bits for literal/length code
					n--;
					b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
				}

				t = b & ml;
				tp = tl;
				tp_index = tl_index;
				tp_index_t_3 = (tp_index + t) * 3;
				if ((e = tp[tp_index_t_3]) == 0)
				{
					b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);

					s.window[q++] = (byte)tp[tp_index_t_3 + 2];
					m--;
					continue;
				}
				do
				{

					b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);

					if ((e & 16) != 0)
					{
						e &= 15;
						c = tp[tp_index_t_3 + 2] + ((int)b & inflate_mask[e]);

						b >>= e; k -= e;

						// decode distance base of block to copy
						while (k < (15))
						{
							// max bits for distance code
							n--;
							b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
						}

						t = b & md;
						tp = td;
						tp_index = td_index;
						tp_index_t_3 = (tp_index + t) * 3;
						e = tp[tp_index_t_3];

						do
						{

							b >>= (tp[tp_index_t_3 + 1]); k -= (tp[tp_index_t_3 + 1]);

							if ((e & 16) != 0)
							{
								// get extra bits to add to distance base
								e &= 15;
								while (k < (e))
								{
									// get extra bits (up to 13)
									n--;
									b |= (z.InputBuffer[p++] & 0xff) << k; k += 8;
								}

								d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);

								b >>= (e); k -= (e);

								// do the copy
								m -= c;
								if (q >= d)
								{
									// offset before dest
									//  just copy
									r = q - d;
									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
										c -= 2;
									}
									else
									{
										Array.Copy(s.window, r, s.window, q, 2);
										q += 2; r += 2; c -= 2;
									}
								}
								else
								{
									// else offset after destination
									r = q - d;
									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 += (b & inflate_mask[e]);
								tp_index_t_3 = (tp_index + t) * 3;
								e = tp[tp_index_t_3];
							}
							else
							{
								z.Message = "invalid distance code";

								c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);

								s.bitb = b; s.bitk = k;
								z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
								s.write = q;

								return ZlibConstants.Z_DATA_ERROR;
							}
						}
						while (true);
						break;
					}

					if ((e & 64) == 0)
					{
						t += tp[tp_index_t_3 + 2];
						t += (b & inflate_mask[e]);
						tp_index_t_3 = (tp_index + t) * 3;
						if ((e = tp[tp_index_t_3]) == 0)
						{

							b >>= (tp[tp_index_t_3 + 1]); k -= (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 - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);

						s.bitb = b; s.bitk = k;
						z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
						s.write = q;

						return ZlibConstants.Z_STREAM_END;
					}
					else
					{
						z.Message = "invalid literal/length code";

						c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);

						s.bitb = b; s.bitk = k;
						z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
						s.write = q;

						return ZlibConstants.Z_DATA_ERROR;
					}
				}
				while (true);
			}
			while (m >= 258 && n >= 10);

			// not enough input or output--restore pointers and return
			c = z.AvailableBytesIn - n; c = (k >> 3) < c ? k >> 3 : c; n += c; p -= c; k -= (c << 3);

			s.bitb = b; s.bitk = k;
			z.AvailableBytesIn = n; z.TotalBytesIn += p - z.NextIn; z.NextIn = p;
			s.write = q;

			return ZlibConstants.Z_OK;
		}
Exemplo n.º 8
0
		internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w)
		{
			_codec = codec;
			hufts = new int[MANY * 3];
			window = new byte[w];
			end = w;
			this.checkfn = checkfn;
			mode = TYPE;
			Reset(null);
		}
Exemplo n.º 9
0
        private void End()
        {
            if (this.Z == null)
                return;

            //if (_wantCompress)
            //{
            //    _z.EndDeflate();
            //}
            //else
            //{
            this.z.EndInflate();
            //}

            this.z = null;
        }
Exemplo n.º 10
0
 internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
 {
     this.Codec = codec;
     this.Hufts = new int[MANY * 3];
     this.Window = new byte[w];
     this.End = w;
     this.Checkfn = checkfn;
     this.Mode = TYPE;
     this.Reset(null);
 }
Exemplo n.º 11
0
 internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
 {
     bl[0] = FIXED_BL;
     bd[0] = FIXED_BD;
     tl[0] = FixedTl;
     td[0] = FixedTd;
     return Z_OK;
 }
Exemplo n.º 12
0
 internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z)
 {
     bl[0] = fixed_bl;
     bd[0] = fixed_bd;
     tl[0] = fixed_tl;
     td[0] = fixed_td;
     return(Z_OK);
 }
Exemplo n.º 13
0
        internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z)
        {
            int result;

            // build literal/length tree
            initWorkArea(288);
            hn[0]  = 0;
            result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
            if (result != Z_OK || bl[0] == 0)
            {
                if (result == Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed literal/length tree";
                }
                else if (result != Z_MEM_ERROR)
                {
                    z.Message = "incomplete literal/length tree";
                    result    = Z_DATA_ERROR;
                }
                return(result);
            }

            // build distance tree
            initWorkArea(288);
            result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);

            if (result != Z_OK || (bd[0] == 0 && nl > 257))
            {
                if (result == Z_DATA_ERROR)
                {
                    z.Message = "oversubscribed distance tree";
                }
                else if (result == Z_BUF_ERROR)
                {
                    z.Message = "incomplete distance tree";
                    result    = Z_DATA_ERROR;
                }
                else if (result != Z_MEM_ERROR)
                {
                    z.Message = "empty distance tree with lengths";
                    result    = Z_DATA_ERROR;
                }
                return(result);
            }

            return(Z_OK);
        }