private bool DeflateSlow()

in src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs [741:855]


		private bool DeflateSlow(bool flush, bool finish)
		{
			if (lookahead < DeflaterConstants.MIN_LOOKAHEAD && !flush)
			{
				return false;
			}

			while (lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush)
			{
				if (lookahead == 0)
				{
					if (prevAvailable)
					{
						huffman.TallyLit(window[strstart - 1] & 0xff);
					}
					prevAvailable = false;

					// We are flushing everything
#if DebugDeflation
					if (DeflaterConstants.DEBUGGING && !flush)
					{
						throw new SharpZipBaseException("Not flushing, but no lookahead");
					}
#endif
					huffman.FlushBlock(window, blockStart, strstart - blockStart,
						finish);
					blockStart = strstart;
					return false;
				}

				if (strstart >= 2 * DeflaterConstants.WSIZE - DeflaterConstants.MIN_LOOKAHEAD)
				{
					/* slide window, as FindLongestMatch needs this.
					 * This should only happen when flushing and the window
					 * is almost full.
					 */
					SlideWindow();
				}

				int prevMatch = matchStart;
				int prevLen = matchLen;
				if (lookahead >= DeflaterConstants.MIN_MATCH)
				{
					int hashHead = InsertString();

					if (strategy != DeflateStrategy.HuffmanOnly &&
						hashHead != 0 &&
						strstart - hashHead <= DeflaterConstants.MAX_DIST &&
						FindLongestMatch(hashHead))
					{
						// longestMatch sets matchStart and matchLen

						// Discard match if too small and too far away
						if (matchLen <= 5 && (strategy == DeflateStrategy.Filtered || (matchLen == DeflaterConstants.MIN_MATCH && strstart - matchStart > TooFar)))
						{
							matchLen = DeflaterConstants.MIN_MATCH - 1;
						}
					}
				}

				// previous match was better
				if ((prevLen >= DeflaterConstants.MIN_MATCH) && (matchLen <= prevLen))
				{
#if DebugDeflation
					if (DeflaterConstants.DEBUGGING)
					{
					   for (int i = 0 ; i < matchLen; i++) {
						  if (window[strstart-1+i] != window[prevMatch + i])
							 throw new SharpZipBaseException();
						}
					}
#endif
					huffman.TallyDist(strstart - 1 - prevMatch, prevLen);
					prevLen -= 2;
					do
					{
						strstart++;
						lookahead--;
						if (lookahead >= DeflaterConstants.MIN_MATCH)
						{
							InsertString();
						}
					} while (--prevLen > 0);

					strstart++;
					lookahead--;
					prevAvailable = false;
					matchLen = DeflaterConstants.MIN_MATCH - 1;
				}
				else
				{
					if (prevAvailable)
					{
						huffman.TallyLit(window[strstart - 1] & 0xff);
					}
					prevAvailable = true;
					strstart++;
					lookahead--;
				}

				if (huffman.IsFull())
				{
					int len = strstart - blockStart;
					if (prevAvailable)
					{
						len--;
					}
					bool lastBlock = (finish && (lookahead == 0) && !prevAvailable);
					huffman.FlushBlock(window, blockStart, len, lastBlock);
					blockStart += len;
					return !lastBlock;
				}
			}
			return true;
		}