⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deflate.java

📁 纯Java实现的ZIP文件压缩解压类库,JDK中的ZIP类库源码中有一些native方法
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
      }    }    if(match_available!=0) {      bflush=_tr_tally(0, window[strstart-1]&0xff);      match_available = 0;    }    flush_block_only(flush == Z_FINISH);    if(strm.avail_out==0){      if(flush == Z_FINISH) return FinishStarted;      else return NeedMore;    }    return flush == Z_FINISH ? FinishDone : BlockDone;  }  int longest_match(int cur_match){    int chain_length = max_chain_length; // max hash chain length    int scan = strstart;                 // current string    int match;                           // matched string    int len;                             // length of current match    int best_len = prev_length;          // best match length so far    int limit = strstart>(w_size-MIN_LOOKAHEAD) ?      strstart-(w_size-MIN_LOOKAHEAD) : 0;    int nice_match=this.nice_match;    // Stop when cur_match becomes <= limit. To simplify the code,    // we prevent matches with the string of window index 0.    int wmask = w_mask;    int strend = strstart + MAX_MATCH;    byte scan_end1 = window[scan+best_len-1];    byte scan_end = window[scan+best_len];    // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.    // It is easy to get rid of this optimization if necessary.    // Do not waste too much time if we already have a good match:    if (prev_length >= good_match) {      chain_length >>= 2;    }    // Do not look for matches beyond the end of the input. This is necessary    // to make deflate deterministic.    if (nice_match > lookahead) nice_match = lookahead;    do {      match = cur_match;      // Skip to next match if the match length cannot increase      // or if the match length is less than 2:      if (window[match+best_len]   != scan_end  ||	  window[match+best_len-1] != scan_end1 ||	  window[match]       != window[scan]     ||	  window[++match]     != window[scan+1])      continue;      // The check at best_len-1 can be removed because it will be made      // again later. (This heuristic is not always a win.)      // It is not necessary to compare scan[2] and match[2] since they      // are always equal when the other bytes match, given that      // the hash keys are equal and that HASH_BITS >= 8.      scan += 2; match++;      // We check for insufficient lookahead only every 8th comparison;      // the 256th check will be made at strstart+258.      do {      } while (window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       window[++scan] == window[++match] &&	       scan < strend);      len = MAX_MATCH - (int)(strend - scan);      scan = strend - MAX_MATCH;      if(len>best_len) {	match_start = cur_match;	best_len = len;	if (len >= nice_match) break;	scan_end1  = window[scan+best_len-1];	scan_end   = window[scan+best_len];      }    } while ((cur_match = (prev[cur_match & wmask]&0xffff)) > limit	     && --chain_length != 0);    if (best_len <= lookahead) return best_len;    return lookahead;  }      int deflateInit(ZStream strm, int level, int bits){    return deflateInit2(strm, level, Z_DEFLATED, bits, DEF_MEM_LEVEL,			Z_DEFAULT_STRATEGY);  }  int deflateInit(ZStream strm, int level){    return deflateInit(strm, level, MAX_WBITS);  }  int deflateInit2(ZStream strm, int level, int method,  int windowBits,		   int memLevel, int strategy){    int noheader = 0;    //    byte[] my_version=ZLIB_VERSION;    //    //  if (version == null || version[0] != my_version[0]    //  || stream_size != sizeof(z_stream)) {    //  return Z_VERSION_ERROR;    //  }    strm.msg = null;    if (level == Z_DEFAULT_COMPRESSION) level = 6;    if (windowBits < 0) { // undocumented feature: suppress zlib header      noheader = 1;      windowBits = -windowBits;    }    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || 	method != Z_DEFLATED ||	windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||        strategy < 0 || strategy > Z_HUFFMAN_ONLY) {      return Z_STREAM_ERROR;    }    strm.dstate = (Deflate)this;    this.noheader = noheader;    w_bits = windowBits;    w_size = 1 << w_bits;    w_mask = w_size - 1;    hash_bits = memLevel + 7;    hash_size = 1 << hash_bits;    hash_mask = hash_size - 1;    hash_shift = ((hash_bits+MIN_MATCH-1)/MIN_MATCH);    window = new byte[w_size*2];    prev = new short[w_size];    head = new short[hash_size];    lit_bufsize = 1 << (memLevel + 6); // 16K elements by default    // We overlay pending_buf and d_buf+l_buf. This works since the average    // output size for (length,distance) codes is <= 24 bits.    pending_buf = new byte[lit_bufsize*4];    pending_buf_size = lit_bufsize*4;    d_buf = lit_bufsize/2;    l_buf = (1+2)*lit_bufsize;    this.level = level;//System.out.println("level="+level);    this.strategy = strategy;    this.method = (byte)method;    return deflateReset(strm);  }  int deflateReset(ZStream strm){    strm.total_in = strm.total_out = 0;    strm.msg = null; //    strm.data_type = Z_UNKNOWN;    pending = 0;    pending_out = 0;    if(noheader < 0) {      noheader = 0; // was set to -1 by deflate(..., Z_FINISH);    }    status = (noheader!=0) ? BUSY_STATE : INIT_STATE;    strm.adler=strm._adler.adler32(0, null, 0, 0);    last_flush = Z_NO_FLUSH;    tr_init();    lm_init();    return Z_OK;  }  int deflateEnd(){    if(status!=INIT_STATE && status!=BUSY_STATE && status!=FINISH_STATE){      return Z_STREAM_ERROR;    }    // Deallocate in reverse order of allocations:    pending_buf=null;    head=null;    prev=null;    window=null;    // free    // dstate=null;    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;  }  int deflateParams(ZStream strm, int _level, int _strategy){    int err=Z_OK;    if(_level == Z_DEFAULT_COMPRESSION){      _level = 6;    }    if(_level < 0 || _level > 9 ||        _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {      return Z_STREAM_ERROR;    }    if(config_table[level].func!=config_table[_level].func &&       strm.total_in != 0) {      // Flush the last buffer:      err = strm.deflate(Z_PARTIAL_FLUSH);    }    if(level != _level) {      level = _level;      max_lazy_match   = config_table[level].max_lazy;      good_match       = config_table[level].good_length;      nice_match       = config_table[level].nice_length;      max_chain_length = config_table[level].max_chain;    }    strategy = _strategy;    return err;  }  int deflateSetDictionary (ZStream strm, byte[] dictionary, int dictLength){    int length = dictLength;    int index=0;    if(dictionary == null || status != INIT_STATE)      return Z_STREAM_ERROR;    strm.adler=strm._adler.adler32(strm.adler, dictionary, 0, dictLength);    if(length < MIN_MATCH) return Z_OK;    if(length > w_size-MIN_LOOKAHEAD){      length = w_size-MIN_LOOKAHEAD;      index=dictLength-length; // use the tail of the dictionary    }    System.arraycopy(dictionary, index, window, 0, length);    strstart = length;    block_start = length;    // Insert all strings in the hash table (except for the last two bytes).    // s->lookahead stays null, so s->ins_h will be recomputed at the next    // call of fill_window.    ins_h = window[0]&0xff;    ins_h=(((ins_h)<<hash_shift)^(window[1]&0xff))&hash_mask;    for(int n=0; n<=length-MIN_MATCH; n++){      ins_h=(((ins_h)<<hash_shift)^(window[(n)+(MIN_MATCH-1)]&0xff))&hash_mask;      prev[n&w_mask]=head[ins_h];      head[ins_h]=(short)n;    }    return Z_OK;  }  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:      }      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;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -