All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.webcodepro.shrinkit.io.LzwOutputStream Maven / Gradle / Ivy

package com.webcodepro.shrinkit.io;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import com.webcodepro.shrinkit.CRC16;

/**
 * This is the generic Shrinkit LZW compression algorithm.
 * It does not deal with the vagaries of the LZW/1 and LZW/2 data streams.
 *  
 * @author [email protected]
 */
public class LzwOutputStream extends OutputStream {
	private BitOutputStream os;
	private Map dictionary = new HashMap();
	private int[] w = new int[0];
	private int nextCode = 0x101;
	
	/**
	 * This simple class can be used as a key into a Map.
	 *  
	 * @author [email protected]
	 */
	private class ByteArray {
		/** Data being managed. */
		private int[] data;
		/** The computed hash code -- CRC-16 for lack of imagination. */
		private int hashCode;
		
		public ByteArray(int d) {
			this(new int[] { d });
		}
		public ByteArray(int[] data) {
			this.data = data;
			CRC16 crc = new CRC16();
			for (int b : data) crc.update(b);
			hashCode = (int)crc.getValue();
		}
		public boolean equals(Object obj) {
			ByteArray ba = (ByteArray)obj;
			if (data.length != ba.data.length) return false;
			for (int i=0; i 0) System.arraycopy(w, 0, wc, 0, w.length);
		wc[wc.length-1]= c;
		if (dictionary.containsKey(new ByteArray(wc))) {
			w = wc;
		} else {
			dictionary.put(new ByteArray(wc), nextCode++);
			os.write(dictionary.get(new ByteArray(w)));
			w = new int[] { c };
		}
		// Exclusive-OR the current bitmask against the new dictionary size -- if all bits are
		// on, we'll get 0.  (That is, all 9 bits on is 0x01ff exclusive or bit mask of 0x01ff 
		// yields 0x0000.)  This tells us we need to increase the number of bits we're writing
		// to the bit stream.
		if ((dictionary.size() ^ os.getBitMask()) == 0) {
			os.increaseRequestedNumberOfBits();
		}
	}

	@Override
	public void flush() throws IOException {
		os.write(dictionary.get(new ByteArray(w)));
	}
	
	@Override
	public void close() throws IOException {
		flush();
		os.flush();
		os.close();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy