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())));
		
	}


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

相关文章推荐

C++实现LZW压缩和解压

  • 2013年06月15日 21:05
  • 2KB
  • 下载

LZW的压缩和解压缩(c++)

  • 2010年12月16日 15:20
  • 1.97MB
  • 下载

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

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

LZW压缩算法

介绍 LZW算法是非常常见的一种压缩算法,他的压缩原理是对于多次重复出现的字符串,进行压缩,至于怎么压缩,在后文中会细细描述,LZW算法可以用在很多的场合,诸如图像压缩,文本压缩等等,而且算法简单易...

JS LZW算法压缩与解压

JS LZW算法压缩与解压,一个JavaScript二进制接口源码,LZW 压缩解压算法,压缩比确实不错,代码不超过200行。 LZW 压缩解压 * { font-size:12px} body...

LZW数据压缩算法的原理分析

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

lzw图像压缩算法

using System; using System.IO; namespace Gif.Components { public class LZWEncoder { private static r...

lzw字符串压缩算法实现

lzw算法思想举例: 原输入数据为:A B A B A B A B B B A B A B A A C D A C D A D C A B A A A B A B ..... 采用LZW算法对其进行...

LZW 压缩算法的C++实现

最近老师布置了一个上机作业,实现LZW 。刚好最近对STL掌握的还不错,写起来就比较容易,又一次体会到了C++模版库的强大,要不然代码量就*2了。 不知道老师的要求是对ASCCI码所有的字符进行压缩...

LZW压缩算法编解码示例

LZW压缩算法是Lempel-Ziv-Welch 3个人共同发明的,简称 LZW 的压缩算法,可以用任何一种语言来实现它. LZW是GIF图片文件的压缩算法,而且zip压缩的思想也是基于LZW实现的...
  • pymqq
  • pymqq
  • 2014年04月03日 15:32
  • 1288
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:LZW算法压缩和解压缩
举报原因:
原因补充:

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