private bool?DecodeTop(ref bool endOfBlock, ref int freeBytes) { int nextSymbol = this.literalLengthTree.GetNextSymbol(this.input); if (nextSymbol < 0) { return(new bool?(false)); } if (nextSymbol >= 256) { if (nextSymbol == 256) { endOfBlock = true; this.state = DeflateDecompressor.DecompressorState.ReadingBFinal; return(new bool?(true)); } this.DecodeDistance(ref nextSymbol); this.state = DeflateDecompressor.DecompressorState.HaveInitialLength; } else { this.output.AddByte((byte)nextSymbol); --freeBytes; } return(new bool?()); }
private bool ReadTreeCodes() { while (this.loopCounter < this.codeArraySize) { if (this.state == DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore) { this.lengthCode = this.codeLengthTree.GetNextSymbol(this.input); if (this.lengthCode < 0) { return(false); } } if (this.lengthCode > 15) { if (!this.input.CheckAvailable(7)) { this.state = DeflateDecompressor.DecompressorState.ReadingTreeCodesAfter; return(false); } this.SetPreviousCode(); } else { this.codeList[this.loopCounter++] = (byte)this.lengthCode; } this.state = DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore; } this.SetTreeCodes(); this.state = DeflateDecompressor.DecompressorState.DecodeTop; return(true); }
private bool CheckDecodeState() { bool endOfBlock = false; bool flag; if (this.blockType == DeflateDecompressor.BlockType.Dynamic) { flag = this.state < DeflateDecompressor.DecompressorState.DecodeTop ? this.DecodeDynamicBlockHeader() : this.DecodeBlock(out endOfBlock); } else if (this.blockType != DeflateDecompressor.BlockType.Static) { if (this.blockType != DeflateDecompressor.BlockType.Stored) { DeflateDecompressor.ThrowUnknownBlockType(); } flag = this.DecodeUncompressedBlock(out endOfBlock); } else { flag = this.DecodeBlock(out endOfBlock); } if (endOfBlock && this.bfinal != 0) { this.state = DeflateDecompressor.DecompressorState.Done; } return(flag); }
private bool DecodeDynamicBlockHeader() { switch (this.state) { case DeflateDecompressor.DecompressorState.ReadingNumLitCodes: this.literalLengthCodeCount = this.input.GetBits(5); if (this.literalLengthCodeCount < 0) { return(false); } this.literalLengthCodeCount += 257; this.state = DeflateDecompressor.DecompressorState.ReadingNumDistCodes; goto case DeflateDecompressor.DecompressorState.ReadingNumDistCodes; case DeflateDecompressor.DecompressorState.ReadingNumDistCodes: this.distanceCodeCount = this.input.GetBits(5); if (this.distanceCodeCount < 0) { return(false); } ++this.distanceCodeCount; this.state = DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes; goto case DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes; case DeflateDecompressor.DecompressorState.ReadingNumCodeLengthCodes: this.codeLengthCodeCount = this.input.GetBits(4); if (this.codeLengthCodeCount < 0) { return(false); } this.codeLengthCodeCount += 4; this.loopCounter = 0; this.state = DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes; goto case DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes; case DeflateDecompressor.DecompressorState.ReadingCodeLengthCodes: if (!this.DecodeDynamicCodes()) { return(false); } this.state = DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore; goto case DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore; case DeflateDecompressor.DecompressorState.ReadingTreeCodesBefore: case DeflateDecompressor.DecompressorState.ReadingTreeCodesAfter: return(this.ReadTreeCodes()); default: DeflateDecompressor.ThrowUnknownState(); return(true); } }
private bool?DecodeInitialLength() { if (this.extraBits > 0) { int bits = this.input.GetBits(this.extraBits); if (bits < 0) { return(new bool?(false)); } if (this.blockLength < 0 || this.blockLength >= DeflateDecompressor.lengthBase.Length) { DeflateDecompressor.ThrowInvalidData(); } this.blockLength = DeflateDecompressor.lengthBase[this.blockLength] + bits; } this.state = DeflateDecompressor.DecompressorState.HaveFullLength; return(new bool?()); }
private bool?DecodeFullLength() { if (this.blockType != DeflateDecompressor.BlockType.Dynamic) { this.distanceCode = this.input.GetBits(5); if (this.distanceCode >= 0) { this.distanceCode = (int)DeflateDecompressor.staticDistanceTreeTable[this.distanceCode]; } } else { this.distanceCode = this.distanceTree.GetNextSymbol(this.input); } if (this.distanceCode < 0) { return(new bool?(false)); } this.state = DeflateDecompressor.DecompressorState.HaveDistCode; return(new bool?()); }
private bool Decode() { if (this.state == DeflateDecompressor.DecompressorState.ReadingBFinal) { if (!this.input.CheckAvailable(1)) { return(false); } this.bfinal = this.input.GetBits(1); this.state = DeflateDecompressor.DecompressorState.ReadingBType; } if (this.state == DeflateDecompressor.DecompressorState.ReadingBType) { if (!this.input.CheckAvailable(2)) { return(false); } this.ProcessBlockType(); } return(this.CheckDecodeState()); }
private bool?DecodeDistanceCode(ref int freeBytes) { int distance; if (this.distanceCode <= 3) { distance = this.distanceCode + 1; } else { this.extraBits = this.distanceCode - 2 >> 1; int bits = this.input.GetBits(this.extraBits); if (bits < 0) { return(new bool?(false)); } distance = DeflateDecompressor.distanceBasePosition[this.distanceCode] + bits; } this.output.Copy(this.blockLength, distance); freeBytes -= this.blockLength; this.state = DeflateDecompressor.DecompressorState.DecodeTop; return(new bool?()); }
private bool DecodeUncompressedBlock(out bool endOfBlock) { endOfBlock = false; while (this.state != DeflateDecompressor.DecompressorState.DecodingUncompressed) { switch (this.state) { case DeflateDecompressor.DecompressorState.UncompressedAligning: this.input.SkipToByteBoundary(); this.state = DeflateDecompressor.DecompressorState.UncompressedByte1; continue; case DeflateDecompressor.DecompressorState.UncompressedByte1: case DeflateDecompressor.DecompressorState.UncompressedByte2: case DeflateDecompressor.DecompressorState.UncompressedByte3: case DeflateDecompressor.DecompressorState.UncompressedByte4: if (!this.DecodeBits()) { return(false); } continue; default: DeflateDecompressor.ThrowUnknownState(); continue; } } this.blockLength -= this.output.ReadInput(this.input, this.blockLength); if (this.blockLength != 0) { return(this.output.FreeBytes == 0); } this.state = DeflateDecompressor.DecompressorState.ReadingBFinal; endOfBlock = true; return(true); }
private void ProcessBlockType() { this.blockType = (DeflateDecompressor.BlockType) this.input.GetBits(2); switch (this.blockType) { case DeflateDecompressor.BlockType.Stored: this.state = DeflateDecompressor.DecompressorState.UncompressedAligning; break; case DeflateDecompressor.BlockType.Static: this.literalLengthTree = InflateTree.StaticLiteralLengthTree; this.distanceTree = InflateTree.StaticDistanceTree; this.state = DeflateDecompressor.DecompressorState.DecodeTop; break; case DeflateDecompressor.BlockType.Dynamic: this.state = DeflateDecompressor.DecompressorState.ReadingNumLitCodes; break; default: DeflateDecompressor.ThrowUnknownBlockType(); break; } }
private void Reset() { this.state = DeflateDecompressor.DecompressorState.ReadingBFinal; }