LZW算法压缩和解压缩

原创 2015年07月09日 17:39:21

两个处理字典的函数,向字典增加内容,从字典检索内容

	static final int ROOT = 255;
	
	private static int indexOfTables(int[][] tables, int[] data) {
		for (int i=0; i<tables.length && tables[i] != null; i++) {
			boolean eq = false;
			if (tables[i].length == data.length) {
				eq = true;
				for (int j=0; j<tables[i].length; j++) {
					if (tables[i][j] != data[j]) {
						eq = false; 
					}
				}
			}
			
			if (eq ) {
				return i;
			}
		}
		return -1;
	}
	
	private static int[] findFromTables(int[][] tables, int position) {
		if (position < 256) {
			return new int[] {position };
		}
		LinkedList<Integer> list = new LinkedList<>();
		list.add(tables[position][0]);
		if (tables[position].length > 1) {
			list.add(tables[position][1]);
		}
		
		boolean loop = true;
		while (loop) {
			loop = false;
			
			for (int i=0; i<list.size(); i++) {
				position = list.get(i);
				
				if (position > 255) {
					list.remove(i);
					for (int j=0; j<tables[position].length; j++) {
						list.add(i+j, tables[position][j]);
					}
					loop = true;
				}
			}
		}
		int[] r = new int[list.size()];
		for (int i=0; i<r.length; i++) {
			r[i] = list.get(i);
		}
		return r;
	}

LZW压缩编码:

	public static int[] lzw(byte[] source) {
		if (source.length == 0){
			return new int[0];
		}
		
		ArrayList<Integer> output = new ArrayList<>();
		
		int[][] tables = new int[2 << (12-1)][];
		for (int i=0; i<256; i++) {
			tables[i] = new int[1];
			tables[i][0] = i;
		}
		int storeindex = 256;
		
		int prefix = source[0];
		
		for (int i=1; i<source.length; i++) {

			int c = source[i] >=0 ? source[i] : source[i] + 255; // byte2int
			int[] entry = new int[] {prefix, c };
			
			int position = indexOfTables(tables, entry);
			if (position == -1) {
				output.add(prefix);
				tables[storeindex++] = entry;
				prefix = c;
			}
			else {
				prefix = position;
			}
		}
		output.add(prefix);
		
		int[] r = new int[output.size()];
		for (int i=0; i<r.length; i++) {
			r[i] = output.get(i);
		}
		
		return r;
	}


LZW解压:

	public static byte[] unlzw(int[] source) {
		if (source.length == 0) {
			return new byte[0];
		}
		if (source.length == 1) {
			return new byte[] { (byte)source[0] };
		}
		
		int[][] tables = new int[2 << (12-1)][];
		for (int i=0; i<256; i++) {
			tables[i] = new int[1];
			tables[i][0] = i;
		}
		int storeindex =  256;
		
		ArrayList<Byte> output = new ArrayList<>();
		int prefix = source[0];
		int prefixPrefix = prefix;
		
		output.add((byte) source[0]);
		
		for (int i=1; i<source.length; i++) {

			int c = source[i];
			int[] data = null;

			if (c >= storeindex) {
				data = findFromTables(tables, prefix);
				int[] t = new int[data.length + 1];
				System.arraycopy(data, 0, t, 0, data.length);
				t[t.length - 1] =  prefixPrefix;
				data = t;
			}
			else {
				 data = findFromTables(tables, c);
			}
			
			prefixPrefix = data[0];
			int[] entry = new int[] {prefix, data[0]};
			tables[storeindex++] = entry;
			
			prefix = c;
				
			for (int j=0; j<data.length; j++) {
				output.add((byte) data[j] );
			}

		}
		
		byte[] r = new byte[output.size()];
		for (int i=0; i<r.length; i++) {
			r[i] = output.get(i);
		}
		return r;
	}

测试程序:

	@org.junit.Test
	public void test() {
	
		org.junit.Assert.assertArrayEquals("eeeee".getBytes(), LZW.unlzw(LZW.lzw("eeeee".getBytes())));
		
		org.junit.Assert.assertArrayEquals("eeeeeeeeeee".getBytes(), LZW.unlzw(LZW.lzw("eeeeeeeeeee".getBytes())));
		
		org.junit.Assert.assertArrayEquals("ababbabbbabbbb".getBytes(), LZW.unlzw(LZW.lzw("ababbabbbabbbb".getBytes())));
		
		org.junit.Assert.assertArrayEquals("aabbccaaabbbcccabcaaaabbbbcccc".getBytes(), LZW.unlzw(LZW.lzw("aabbccaaabbbcccabcaaaabbbbcccc".getBytes())));
		
	}


版权声明:本文为博主原创文章,未经博主允许不得转载。

LZW压缩(解压缩)算法详解及源码

from: http://blog.chinaunix.net/uid-23741326-id-3124208.html LZW压缩算法是Lempel-Ziv-Welch 3个人共同发明的,...
  • xiongbixb2
  • xiongbixb2
  • 2015年11月08日 11:38
  • 2234

LZW压缩(解压缩)算法详解及源码

  • 2014年08月28日 16:48
  • 991KB
  • 下载

LZW压缩算法

  • 2015年12月20日 14:56
  • 3.72MB
  • 下载

LZW算法实现的压缩与解压缩程序的C源代码

  • 2011年06月16日 17:58
  • 102KB
  • 下载

【数据压缩】LZW算法原理与源码解析

LZW压缩算法原理非常简单,因而被广泛地采用,已经被引入主流图像文件格式中。该算法由Lempel-Ziv-Welch三人发明,这种技术将定长码字分配给变长信源符号序列,它不需要知道被压缩文件的符号出现...
  • luoshixian099
  • luoshixian099
  • 2015年12月17日 21:48
  • 5662

LZW压缩(解压缩)算法详解及源码

from: http://blog.chinaunix.net/uid-23741326-id-3124208.html LZW压缩算法是Lempel-Ziv-Welch 3个人共同发明的,...
  • xiongbixb2
  • xiongbixb2
  • 2015年11月08日 11:38
  • 2234

lzw压缩算法及解码算法

  • 2011年04月07日 13:05
  • 911KB
  • 下载

LZW数据压缩算法的原理分析 - jillzhang - 博客园

导读:  我希望通过本文的介绍,能给那些目前不太了解lzw算法和该算法在gif图像中应用,但渴望了解它的人一些启发和帮助。抛砖引玉而已,更希望园子里面兄弟提出宝贵的意见。1.LZW的全称是什么?  ...
  • chief1985
  • chief1985
  • 2008年04月19日 22:53
  • 2136

LZW压缩(解压缩)算法详解

LZW压缩算法是Lempel-Ziv-Welch 3个人共同发明的,简称 LZW 的压缩算法,可以用任何一种语言来实现它. LZW是GIF图片文件的压缩算法,而且zip压缩的思想也是基于LZW实现的...
  • lubeijing2008xu
  • lubeijing2008xu
  • 2014年05月15日 20:37
  • 2287

LZW 文本压缩及解压

LZW就是通过建立一个字符串表,用较短的代码来表示较长的字符串来实现压缩。 压缩算法如下 #include #include std::ifstream fin; std::ofstream...
  • xianyun2009
  • xianyun2009
  • 2014年09月15日 12:10
  • 1346
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LZW算法压缩和解压缩
举报原因:
原因补充:

(最多只允许输入30个字)