public override int Read(byte[] buffer, int offset, int count) { if (compress) { return(0); } int size = 0; if (properties.Version == PpmdVersion.I1) { size = model.DecodeBlock(stream, buffer, offset, count); } if (properties.Version == PpmdVersion.H) { int c; while (size < count && (c = modelH.decodeChar()) >= 0) { buffer[offset++] = (byte)c; size++; } } if (properties.Version == PpmdVersion.H7z) { int c; while (size < count && (c = modelH.decodeChar(decoder)) >= 0) { buffer[offset++] = (byte)c; size++; } } position += size; return(size); }
private void unpack29(bool solid) { int[] DDecode = new int[Compress.DC]; byte[] DBits = new byte[Compress.DC]; int Bits; if (DDecode[1] == 0) { int Dist = 0, BitLength = 0, Slot = 0; for (int I = 0; I < DBitLengthCounts.Length; I++, BitLength++) { int count = DBitLengthCounts[I]; for (int J = 0; J < count; J++, Slot++, Dist += (1 << BitLength)) { DDecode[Slot] = Dist; DBits[Slot] = (byte)BitLength; } } } fileExtracted = true; if (!suspended) { unpInitData(solid); if (!unpReadBuf()) { return; } if ((!solid || !tablesRead) && !readTables()) { return; } } if (ppmError) { return; } while (true) { unpPtr &= Compress.MAXWINMASK; if (inAddr > readBorder) { if (!unpReadBuf()) { break; } } // System.out.println(((wrPtr - unpPtr) & // Compress.MAXWINMASK)+":"+wrPtr+":"+unpPtr); if (((wrPtr - unpPtr) & Compress.MAXWINMASK) < 260 && wrPtr != unpPtr) { UnpWriteBuf(); if (destUnpSize <= 0) { return; } if (suspended) { fileExtracted = false; return; } } if (unpBlockType == BlockTypes.BLOCK_PPM) { int Ch = ppm.decodeChar(); if (Ch == -1) { ppmError = true; break; } if (Ch == ppmEscChar) { int NextCh = ppm.decodeChar(); if (NextCh == 0) { if (!readTables()) { break; } continue; } if (NextCh == 2 || NextCh == -1) { break; } if (NextCh == 3) { if (!readVMCodePPM()) { break; } continue; } if (NextCh == 4) { int Distance = 0, Length = 0; bool failed = false; for (int I = 0; I < 4 && !failed; I++) { int ch = ppm.decodeChar(); if (ch == -1) { failed = true; } else { if (I == 3) { // Bug fixed Length = ch & 0xff; } else { // Bug fixed Distance = (Distance << 8) + (ch & 0xff); } } } if (failed) { break; } copyString(Length + 32, Distance + 2); continue; } if (NextCh == 5) { int Length = ppm.decodeChar(); if (Length == -1) { break; } copyString(Length + 4, 1); continue; } } window[unpPtr++] = (byte)Ch; continue; } int Number = this.decodeNumber(LD); if (Number < 256) { window[unpPtr++] = (byte)Number; continue; } if (Number >= 271) { int Length = LDecode[Number -= 271] + 3; if ((Bits = LBits[Number]) > 0) { Length += Utility.URShift(GetBits(), (16 - Bits)); AddBits(Bits); } int DistNumber = this.decodeNumber(DD); int Distance = DDecode[DistNumber] + 1; if ((Bits = DBits[DistNumber]) > 0) { if (DistNumber > 9) { if (Bits > 4) { Distance += ((Utility.URShift(GetBits(), (20 - Bits))) << 4); AddBits(Bits - 4); } if (lowDistRepCount > 0) { lowDistRepCount--; Distance += prevLowDist; } else { int LowDist = this.decodeNumber(LDD); if (LowDist == 16) { lowDistRepCount = Compress.LOW_DIST_REP_COUNT - 1; Distance += prevLowDist; } else { Distance += LowDist; prevLowDist = LowDist; } } } else { Distance += Utility.URShift(GetBits(), (16 - Bits)); AddBits(Bits); } } if (Distance >= 0x2000) { Length++; if (Distance >= 0x40000L) { Length++; } } insertOldDist(Distance); insertLastMatch(Length, Distance); copyString(Length, Distance); continue; } if (Number == 256) { if (!readEndOfBlock()) { break; } continue; } if (Number == 257) { if (!readVMCode()) { break; } continue; } if (Number == 258) { if (lastLength != 0) { copyString(lastLength, lastDist); } continue; } if (Number < 263) { int DistNum = Number - 259; int Distance = oldDist[DistNum]; for (int I = DistNum; I > 0; I--) { oldDist[I] = oldDist[I - 1]; } oldDist[0] = Distance; int LengthNumber = this.decodeNumber(RD); int Length = LDecode[LengthNumber] + 2; if ((Bits = LBits[LengthNumber]) > 0) { Length += Utility.URShift(GetBits(), (16 - Bits)); AddBits(Bits); } insertLastMatch(Length, Distance); copyString(Length, Distance); continue; } if (Number < 272) { int Distance = SDDecode[Number -= 263] + 1; if ((Bits = SDBits[Number]) > 0) { Distance += Utility.URShift(GetBits(), (16 - Bits)); AddBits(Bits); } insertOldDist(Distance); insertLastMatch(2, Distance); copyString(2, Distance); continue; } } UnpWriteBuf(); }