internal int deflate(ZStream strm, int flush){ int old_flush; if(flush>Z_FINISH || flush<0){ return Z_STREAM_ERROR; } if(strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == FINISH_STATE && flush != Z_FINISH)) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_STREAM_ERROR)]; return Z_STREAM_ERROR; } if(strm.avail_out == 0){ strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } this.strm = strm; // just in case old_flush = last_flush; last_flush = flush; // Write the zlib header if(status == INIT_STATE) { int header = (Z_DEFLATED+((w_bits-8)<<4))<<8; int level_flags=((level-1)&0xff)>>1; if(level_flags>3) level_flags=3; header |= (level_flags<<6); if(strstart!=0) header |= PRESET_DICT; header+=31-(header % 31); status=BUSY_STATE; putShortMSB(header); // Save the adler32 of the preset dictionary: if(strstart!=0){ putShortMSB((int)(strm.adler>>16)); putShortMSB((int)(strm.adler&0xffff)); } strm.adler=strm._adler.adler32(0, null, 0, 0); } // Flush as much pending output as possible if(pending != 0) { strm.flush_pending(); if(strm.avail_out == 0) { //System.out.println(" avail_out==0"); // Since avail_out is 0, deflate will be called again with // more output space, but possibly with both pending and // avail_in equal to zero. There won't be anything to do, // but this is not an error situation so make sure we // return OK instead of BUF_ERROR at next call of deflate: last_flush = -1; return Z_OK; } // Make sure there is something to do and avoid duplicate consecutive // flushes. For repeated and useless calls with Z_FINISH, we keep // returning Z_STREAM_END instead of Z_BUFF_ERROR. } else if(strm.avail_in==0 && flush <= old_flush && flush != Z_FINISH) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } // User must not provide more input after the first FINISH: if(status == FINISH_STATE && strm.avail_in != 0) { strm.msg=z_errmsg[Z_NEED_DICT-(Z_BUF_ERROR)]; return Z_BUF_ERROR; } // Start a new block or continue the current one. if(strm.avail_in!=0 || lookahead!=0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) { int bstate=-1; switch(config_table[level].func){ case STORED: bstate = deflate_stored(flush); break; case FAST: bstate = deflate_fast(flush); break; case SLOW: bstate = deflate_slow(flush); break; default: break; } if (bstate==FinishStarted || bstate==FinishDone) { status = FINISH_STATE; } if (bstate==NeedMore || bstate==FinishStarted) { if(strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR next call, see above } return Z_OK; // If flush != Z_NO_FLUSH && avail_out == 0, the next call // of deflate should use the same flush parameter to make sure // that the flush is complete. So we don't have to output an // empty block here, this will be done at next call. This also // ensures that for a very small output buffer, we emit at most // one empty block. } if (bstate==BlockDone) { if(flush == Z_PARTIAL_FLUSH) { _tr_align(); } else { // FULL_FLUSH or SYNC_FLUSH _tr_stored_block(0, 0, false); // For a full flush, this empty block will be recognized // as a special marker by inflate_sync(). if(flush == Z_FULL_FLUSH) { //state.head[s.hash_size-1]=0; for(int i=0; i<hash_size/*-1*/; i++) // forget history head[i]=0; } } strm.flush_pending(); if(strm.avail_out == 0) { last_flush = -1; // avoid BUF_ERROR at next call, see above return Z_OK; } } } if(flush!=Z_FINISH) return Z_OK; if(noheader!=0) return Z_STREAM_END; // Write the zlib trailer (adler32) putShortMSB((int)(strm.adler>>16)); putShortMSB((int)(strm.adler&0xffff)); strm.flush_pending(); // If avail_out is zero, the application will call deflate again // to flush the rest. noheader = -1; // write the trailer only once! return pending != 0 ? Z_OK : Z_STREAM_END; }