public int GetSymbol(StreamManipulator input) { int lookahead, symbol; if ((lookahead = input.PeekBits(9)) >= 0) { if ((symbol = tree[lookahead]) >= 0) { input.DropBits(symbol & 15); return symbol >> 4; } int subtree = -(symbol >> 4); int bitlen = symbol & 15; if ((lookahead = input.PeekBits(bitlen)) >= 0) { symbol = tree[subtree | (lookahead >> 9)]; input.DropBits(symbol & 15); return symbol >> 4; } else { int bits = input.AvailableBits; lookahead = input.PeekBits(bits); symbol = tree[subtree | (lookahead >> 9)]; if ((symbol & 15) <= bits) { input.DropBits(symbol & 15); return symbol >> 4; } else { return -1; } } } else { int bits = input.AvailableBits; lookahead = input.PeekBits(bits); symbol = tree[lookahead]; if (symbol >= 0 && (symbol & 15) <= bits) { input.DropBits(symbol & 15); return symbol >> 4; } else { return -1; } } }
/// <summary> /// Copy from input manipulator to internal window /// </summary> /// <param name="input">source of data</param> /// <param name="length">length of data to copy</param> /// <returns>the number of bytes copied</returns> public int CopyStored(StreamManipulator input, int length) { length = Math.Min(Math.Min(length, WindowSize - windowFilled), input.AvailableBytes); int copied; int tailLen = WindowSize - windowEnd; if (length > tailLen) { copied = input.CopyBytes(window, windowEnd, tailLen); if (copied == tailLen) { copied += input.CopyBytes(window, 0, length - tailLen); } } else { copied = input.CopyBytes(window, windowEnd, length); } windowEnd = (windowEnd + copied) & WindowMask; windowFilled += copied; return copied; }
/// <summary> /// Creates a new inflater. /// </summary> /// <param name="noHeader"> /// True if no RFC1950/Zlib header and footer fields are expected in the input data /// /// This is used for GZIPed/Zipped input. /// /// For compatibility with /// Sun JDK you should provide one byte of input more than needed in /// this case. /// </param> public Inflater(bool noHeader) { this.noHeader = noHeader; //this.adler = new Adler32(); input = new StreamManipulator(); outputWindow = new OutputWindow(); mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER; }
public bool Decode(StreamManipulator input) { decode_loop: for (; ; ) { switch (mode) { case LNUM: lnum = input.PeekBits(5); if (lnum < 0) { return false; } lnum += 257; input.DropBits(5); mode = DNUM; goto case DNUM; case DNUM: dnum = input.PeekBits(5); if (dnum < 0) { return false; } dnum++; input.DropBits(5); num = lnum + dnum; litdistLens = new byte[num]; mode = BLNUM; goto case BLNUM; case BLNUM: blnum = input.PeekBits(4); if (blnum < 0) { return false; } blnum += 4; input.DropBits(4); blLens = new byte[19]; ptr = 0; mode = BLLENS; goto case BLLENS; case BLLENS: while (ptr < blnum) { int len = input.PeekBits(3); if (len < 0) { return false; } input.DropBits(3); blLens[BL_ORDER[ptr]] = (byte)len; ptr++; } blTree = new InflaterHuffmanTree(blLens); blLens = null; ptr = 0; mode = LENS; goto case LENS; case LENS: { int symbol; while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) { litdistLens[ptr++] = lastLen = (byte)symbol; if (ptr == num) { return true; } } if (symbol < 0) { return false; } if (symbol >= 17) { lastLen = 0; } else { if (ptr == 0) { throw new Exception(); } } repSymbol = symbol - 16; } mode = REPS; goto case REPS; case REPS: { int bits = repBits[repSymbol]; int count = input.PeekBits(bits); if (count < 0) { return false; } input.DropBits(bits); count += repMin[repSymbol]; if (ptr + count > num) { throw new Exception(); } while (count-- > 0) { litdistLens[ptr++] = lastLen; } if (ptr == num) { return true; } } mode = LENS; goto decode_loop; } } }