deflate.java
来自「zlib 算法在j2me 中的应用」· Java 代码 · 共 1,764 行 · 第 1/5 页
JAVA
1,764 行
} 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,500,"window"); prev = new_short2(w_size,256,"prev"); head = new_short2(hash_size,256,"head");//32kb not depend on amount of data 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,500,"pending_buf"); 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, (byte_array)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); byte_array.Copy(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; ins_h = window.get(0)&0xff; ins_h=(((ins_h)<<hash_shift)^(window.get(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; ins_h=(((ins_h)<<hash_shift)^(window.get((n)+(MIN_MATCH-1))&0xff))&hash_mask; //prev[n&w_mask]=head[ins_h]; prev.set(n&w_mask,head.get(ins_h)); //head[ins_h]=(short)n; head.set(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, (byte_array)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; was originally commented for(int i=0; i<hash_size/*-1*/; i++){ // forget history //head[i]=0; head.set(i,(short)0); }//for } } 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; }//------------------------------------------------------------------- // protected void finalize(){ // //------- // if(DEBUG>0){ // if(depth!=null)System.out.println("Deflate.finalize() depth.totalAllocated()="+depth.totalAllocated()); // if(window!=null)System.out.println("Deflate.finalize() window.totalAllocated()="+window.totalAllocated()); // if(prev!=null)System.out.println("Deflate.finalize() prev.totalAllocated()="+prev.totalAllocated()); // if(head!=null)System.out.println("Deflate.finalize() head.totalAllocated()="+head.totalAllocated()); // if(pending_buf!=null)System.out.println("Deflate.finalize() pending_buf.totalAllocated()="+pending_buf.totalAllocated()); // }//if(DEBUG>0) // //------- // } private static final int[] new_int(int len, String name){ System.out.println("Array of "+name+" = new int["+len+"] allocated in Deflate"); return new int[len]; } private static final short[] new_short(int len, String name){ System.out.println("Array of "+name+" = new short["+len+"] allocated in Deflate"); return new short[len]; } private static final short_array new_short2(int len,int blocklen,String name){ System.out.println("Dynamic array of "+name+" = new short["+len+"] allocated in Deflate"); return new short_array(len,blocklen,"Deflate."+name); } private static final byte_array new_byte(int len, int blocklen, String name){ System.out.println("Dynamic array of "+name+" = new byte["+len+"] allocated in Deflate"); return new byte_array(len,blocklen,"Deflate."+name); } //byte0(int len,String name){ // System.out.println("Array of "+name+" = new byte["+len+"] allocated in Deflate"); // return new byte[len]; // } //------------------------------------------------------------------- }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?