package com.e2u.tree; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import com.e2u.bit.BitUtil; public class Deflater { private String[] encodeTable = null; private int curByte = 0; private int curByteBitLeft = 8; private List<Byte> encodeByteList = null; public Deflater(String[] codeTable) { encodeTable = new String[256]; System.arraycopy(codeTable, 0, encodeTable, 0, encodeTable.length); curByte = 0; curByteBitLeft = 8; encodeByteList = new LinkedList<Byte>(); } private void reset() { curByte = 0; curByteBitLeft = 8; encodeByteList.clear(); } public void addCompressInputData(byte[] data, int len) { String str = null; int tempByte = 0; int offset = 0; for(int i = 0; i < len; i++) { str = encodeTable[BitUtil.unsigned(data[i])]; offset = 0; while(offset < str.length()) { if(str.length() - offset > curByteBitLeft) { tempByte = toByte(str.substring(offset, offset + curByteBitLeft)); offset += curByteBitLeft; curByte |= tempByte; encodeByteList.add((byte) curByte); curByte = 0; curByteBitLeft = 8; } else if(str.length() - offset < curByteBitLeft) { tempByte = toByte(str.substring(offset, str.length())); curByteBitLeft = curByteBitLeft - (str.length() - offset); tempByte <<= curByteBitLeft; curByte |= tempByte; break; } else { tempByte = toByte(str.substring(offset, offset + curByteBitLeft)); curByte |= tempByte; encodeByteList.add((byte) curByte); curByte = 0; curByteBitLeft = 8; break; } } } } public byte[] finishCompress() { // process last byte if(curByteBitLeft == 8) { curByteBitLeft = 0; } if(curByteBitLeft < 8 && curByteBitLeft != 0) { encodeByteList.add((byte) curByte); } // output byte[] result = new byte[encodeByteList.size() + 1]; result[0] = (byte) curByteBitLeft; Iterator<Byte> iter = encodeByteList.iterator(); for(int i = 1; iter.hasNext(); i++) { result[i] = iter.next(); } reset(); return result; } private static int toByte(String str) { int result = 0; char c; for(int i = 0, len = str.length(); i < len; i++) { c = str.charAt(i); if(c == '0') { result = (result << 1); } else if(c == '1') { result = (result << 1) + 1; } else { throw new IllegalArgumentException("Invalid huffman code " + str); } } return result; } }