ImageVerifierCode 换一换
格式:DOCX , 页数:10 ,大小:40.33KB ,
资源ID:8601890      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8601890.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(lzw压缩算法java实现.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

lzw压缩算法java实现.docx

1、lzw压缩算法java实现LZW算法的Java模拟实现一、LZW算法的简介LZW压缩算法是一种新颖的压缩方法,由Lemple-Ziv-Welch 三人共同创造,用他们的名字命名。它采用了一种先进的串表压缩不,将每个第一次出现的串放在一个串表中,用一个数字来表示串,压缩文件只存贮数字,则不存贮串,从而使图象文件的压缩效率得到较大的提高。奇妙的是,不管是在压缩还是在解压缩的过程中都能正确的建立这个串表,压缩或解压缩完成后,这个串表又被丢弃。二、LZW算法的基本原理首先建立一个字符串表,把每一个第一次出现的字符串放入串表中,并用一个数字来表示,这个数字与此字符串在串表中的位置有关,并将这个数字存入压

2、缩文件中,如果这个字符串再次出现时,即可用表示它的数字来代替,并将这个数字存入文件中。压缩完成后将串表丢弃。如print 字符串,如果在压缩时用266表示,只要再次出现,均用266表示,并将print字符串存入串表中,在图象解码时遇到数字266,即可从串表中查出266所代表的字符串print,在解压缩时,串表可以根据压缩数据重新生成。三、LZW算法的实现方法3.1 初始化表在压缩图象信息时,首先要建立一个字符串表,用以记录每个第一次出现的字符串。一个字符串表最少由两个字符数组构成,一个称为当前数组,一个称为前缀数组,因为在GIF文件中每个基本字符串的长度通常为2(但它表示的实际字符串长度可达几

3、百甚至上千),一个基本字符串由当前字符和它前面的字符(也称前缀)构成。前缀数组中存入字符串中的首字符,当前数组存放字符串中的尾字符,其存入位置相同,因此只要确定一个下标,就可确定它所存贮的基本字符串,所以在数据压缩时,用下标代替基本字符串。一般串表大小为4096个字节(即2 的12次方),这意味着一个串表中最多能存贮4096个基本字符串,在初始化时根据图象中色彩数目多少,将串表中起始位置的字节均赋以数字,通常当前数组中的内容为该元素的序号(即下标),如第一个元素为0,第二个元素为1,第15个元素为14 ,直到下标为色彩数目加2的元素为止。如果色彩数为256,则要初始化到第258个字节,该字节中

4、的数值为257。其中数字256表示清除码,数字257 为图象结束码。后面的字节存放文件中每一个第一次出现的串。同样也要音乐会 前缀数组初始化,其中各元素的值为任意数,但一般均将其各位置1,即将开始位置的各元素初始化为0XFF,初始化的元素数目与当前数组相同,其后的元素则要存入每一个第一次出现的字符串了。如果加大串表的长度可进一步提高压缩效率,但会降低解码速度。3.2 压缩方法了解压缩方法时,先要了解几个名词,一是字符流,二是代码流,三是当前码,四是当前前缀。字符流是源图象文件中未经压缩的图象数据;代码流是压缩后写入GIF 文件的压缩图象数据;当前码是从字符流中刚刚读入的字符;当前前缀是刚读入字

5、符前面的字符。GIF 文件在压缩时,不论图象色彩位数是多少,均要将颜色值按字节的单位放入代码流中,每个字节均表示一种颜色。虽然在源图象文件中用一个字节表示16色、4色、2色时会出现4位或更多位的浪费(因为用一个字节中的4位就可以表示16色),但用LZW 压缩法时可回收字节中的空闲位。在压缩时,先从字符流中读取第一个字符作为当前前缀,再取第二个字符作为当前码,当前前缀与当前码构成第一个基本字符串(如当前前缀为A,当前码为B则此字符串即为AB),查串表,此时肯定不会找到同样字符串,则将此字符串写入串表,当前前缀写入前缀数组,当前码写入当前数组,并将当前前缀送入代码流,当前码放入当前前缀,接着读取下

6、一个字符,该字符即为当前码了,此时又形成了一个新的基本字符串 (若当前码为C,则此基本字符串为BC),查串表,若有此串,则丢弃当前前缀中的值,用该串在串表中的位置代码(即下标)作为当前前缀,再读取下一个字符作为当前码,形成新的基本字符串,直到整幅图象压缩完成。由此可看出,在压缩时,前缀数组中的值就是代码流中的字符,大于色彩数目的代码肯定表示一个字符串,而小于或等于色彩数目的代码即为色彩本身。3.3 清除码事实上压缩一幅图象时,常常要对串表进行多次初始化,往往一幅图象中出现的第一次出现的基本字符串个数会超过4096个,在压缩过程中只要字符串的长度超过了4096,就要将当前前缀和当前码输入代码流,

7、并向代码流中加入一个清除码,初始化串表,继续按上述方法进行压缩。3.4 结束码当所有压缩完成后,就向代码流中输出一个图象结束码,其值为色彩数加1,在256色文件中,结束码为257。3.5 字节空间回收在GIF文件输出的代码流中的数据,除了以数据包的形式存放之外,所有的代码均按单位存贮,这样就有效的节省了存贮空间。这如同4位彩色(16色)的图象,按字节存放时,只能利用其中的4位,另外的4位就浪费了,可按位存贮时,每个字节就可以存放两个颜色代码了。事实上在GIF 文件中,使用了一种可变数的存贮方法,由压缩过程可看出,串表前缀数组中各元素的值颁是有规律的,以256色的GIF文件中,第258-511元

8、素中值的范围是0-510 ,正好可用9位的二进制数表示,第512-1023元素中值的范围是0-1022,正好可用10位的二进制数表示,第1024-2047 元素中值的范围是0-2046,正好用11位的二进制数表示,第2048-4095元素中值的范围是0-4094,正好用12位的二进制数表示。用可变位数存贮代码时,基础位数为图象色彩位数加1,随着代码数的增加,位数也在加大,直到位数超过为12(此时字符串表中的字符串个数正好为2 的12次方,即4096个)。 其基本方法是:每向代码流加入一个字符,就要判别此字符所在串在串表中的位置(即下标)是否超过2的当前位数次方,一旦超过,位数加1。如在4位图象

9、中,对于刚开始的代码按5位存贮,第一个字节的低5位放第一个代码,高三位为第二个代码的低3位,第二个字节的低2位放第二个代码的高两位,依次类推。对于8位(256色)的图象,其基础位数就为9,一个代码最小要放在两个字节。3.6 压缩范围以下为256色GIF文件编码实例,如果留心您会发现这是一种奇妙的编码方法,同时为什么在压缩完成后不再需要串表,而且还在解码时根据代码流信息能重新创建串表。字 符 串: 1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,当 前 码: 2,1,1,1,1,2,3,4,1,2,3,4,5,9,当前前缀: 1,2,1,1,260,1,258,3,4,1,258,2

10、62,4,5,当前数组: 2,1,1, 1, 3,4,1, 4,5,9,数组下标: 258,259,260,261,262,263,264,265,266,267,代 码 流: 1,2,1,260,258,3,4,262,4,5,GIF文件作为一种重要的图形图象文件格式,尽管其编码规则极复杂,但其压缩效率是极高的,特别是对某些平滑过渡的图象的图形,压缩效果更好。同时由于其在压缩过程中的对图象信息能够完整的保存,在目前流行的电子图片及电子图书中得到了广泛的应用。四、LZW算法的简单示例对原始数据ABCCAABCDDAACCDB进行LZW压缩,原始数据中,只包括4个字符(Character),A,

11、B,C,D,四个字符可以用一个2bit的数表示,0-A,1-B,2-C,3-D,从最直观的角度看,原始字符串存在重复字符:ABCCAABCDDAACCDB,用4代表AB,5代表CC,上面的字符串可以替代表示为:45A4CDDAA5DB,这样是不是就比原数据短了一些呢!五、LZW算法的适用范围为了区别代表串的值(Code)和原来的单个的数据值(String),需要使它们的数值域不重合,上面用0-3来代表A-D,那么AB就必须用大于3的数值来代替,再举另外一个例子,原来的数值范围可以用8bit来表示,那么就认为原始的数的范围是0255,压缩程序生成的标号的范围就不能为0255(如果是0-255,就

12、重复了)。只能从256开始,但是这样一来就超过了8位的表示范围了,所以必须要扩展数据的位数,至少扩展一位,但是这样不是增加了1个字符占用的空间了么?但是却可以用一个字符代表几个字符,比如原来255是8bit,但是现在用256来表示254,255两个数,还是划得来的。从这个原理可以看出LZW算法的适用范围是原始数据串最好是有大量的子串多次重复出现,重复的越多,压缩效果越好。反之则越差,可能真的不减反增了。六、LZW算法中得特殊标记随着新的串(string)不断被发现,标号也会不断地增长,如果原数据过大,生成的标号集(string table)会越来越大,这时候操作这个集合就会产生效率问题。如何避

13、免这个问题呢?Gif在采用lzw算法的做法是当标号集足够大的时候,就不能增大了,干脆从头开始再来,在这个位置要插入一个标号,就是清除标志CLEAR,表示从这里我重新开始构造字典,以前的所有标记作废,开始使用新的标记。 这时候又有一个问题出现,足够大是多大?这个标号集的大小为比较合适呢?理论上是标号集大小越大,则压缩比率就越高,但开销也越高。 一般根据处理速度和内存空间连个因素来选定。GIF规范规定的是12位,超过12位的表达范围就推倒重来,并且GIF为了提高压缩率,采用的是变长的字长。比如说原始数据是8位,那么一开始,先加上一位再说,开始的字长就成了9位,然后开始加标号,当标号加到512时,也

14、就是超过9为所能表达的最大数据时,也就意味着后面的标号要用10位字长才能表示了,那么从这里开始,后面的字长就是10位了。依此类推,到了212也就是4096时,在这里插一个清除标志,从后面开始,从9位再来。GIF规定的清除标志CLEAR的数值是原始数据字长表示的最大值加1,如果原始数据字长是8,那么清除标志就是256,如果原始数据字长为4那么就是16。另外GIF还规定了一个结束标志END,它的值是清除标志CLEAR再加1。由于GIF规定的位数有1位(单色图),4位(16色)和8位(256色),而1位的情况下如果只扩展1位,只能表示4种状态,那么加上一个清除标志和结束标志就用完了,所以1位的情况下

15、就必须扩充到3位。其它两种情况初始的字长就为5位和9位七、LZW算法的伪代码实现1 STRING = get input character2 WHILE there are still input characters DO3 CHARACTER = get input character4 IF STRING+CHARACTER is in the string table then5 STRING = STRING+character6 ELSE7 output the code for STRING8 add STRING+CHARACTER to the string table9

16、STRING = CHARACTER10 END of IF11 END of WHILE12 output the code for STRING 13 八、LZW算法的流程图九、LZW算法的Java模拟实现package com.anywhere;import java.io.*;public class lzwCodeDictionary dic=new Dictionary();int count1=0,count2=0BufferedInputStream in; BufferedOutputStream out;final short END=4095;/*the entry of

17、 the class,and check the arguments firstparam args array of string arguments-c sourceFile targetFile 建立一个压缩文件-d sourceFile targetFile 解压缩一个文件return No return valueexception No ecceptions thrown*/public static void main(String args)if ( args.length4 )System.out.println(-c sourceFile targetFile -dic 建

18、立一个压缩文件n);System.out.println(-d sourceFile targetFile -dic 解压缩一个文件n);else if(! ( args0.equals(new String(-c) )|args0.equals(new String(-d) ) ) )System.out.println(-c sourceFile targetFile 建立一个压缩文件n);System.out.println(-d sourceFile targetFile 解压缩一个文件n);else if(args.length=2)lzwCode a=new lzwCode(arg

19、s);a.run(args);return ;public lzwCode(String args)tryString f=new String();in =new BufferedInputStream(new FileInputStream(new File(args1);if(args.length=3 & !args2.equals(new String(-dic) f=args2;else int i=args1.lastIndexOf(new String(.) );f=args1.substring(0,i)+(args0.equals(-c) )?.lzw:.dlzw);out

20、=new BufferedOutputStream(new FileOutputStream(new File(f);/trycatch(FileNotFoundException e )System.err.println(e);return;catch(IOException e )System.err.println(e);return;public void run(String args )if(args0.equals(new String(-c) )code(in,out);elsedecode(in,out);if(argsargs.length-1.equals(new St

21、ring(-dic) )System.out.println(dic.toString ();public void code(BufferedInputStream in,BufferedOutputStream out)System.out.println(coding.n+ .n);/a:the buffer byte read from the input file,then to be converted to String/buf: the codestream to store in the code file/prefix :the pre_String of the dict

22、ory/ the indexbuf is the index of dictionary to be converted in / the code file/str: the current charecter of the character input Streambyte a=new byte1,buf=new byte3;String prefix=,cur=;byte i=0;short indexbuf=new short2; String str=null;tryshort m=0;while( (a0=(byte)in.read() ) != -1 )cur=new Stri

23、ng(a);/ be converted count1+; / the number of bytes of input file str=prefix;str=str.concat(cur);m=(short)dic.indexOf(str); if( m!=-1)/the prefix is in the dictionary,prefix=str;else/if(i=0)/the first indexbuf,store in codebuf indexbuf0=(short)dic.indexOf(prefix);i=1;else/ now have 2 index number,th

24、en ouput to the code fileindexbuf1=(short)dic.indexOf(prefix);zipOutput(out,indexbuf);count2+=3;/3 bytes stored to the code file i=0;dic.add(str); prefix=cur;/else/while/ System.out.println(i=+i);if(i=(byte)1) /this is the case that the /input file has only odd index number to storeindexbuf1=END;/pu

25、t a special index number /(the max number of the dictionary) END to the code filezipOutput(out,indexbuf);count2+=3;dic.add(str); in.close ();out.close ();System.out.println(zip rate:+(float)count2*100/count1+% );catch(IOException e )System.err.println(e);return;catch(OutDictionaryException e) System

26、.err.println(e);return; public void decode(BufferedInputStream in,BufferedOutputStream out)System.out.println(decoding.n+.n);short precode=0,curcode=0;String prefix=null;short i=0;short bufcode=new short2;/2 code read from the code fileboolean more=true;/indicate the end of the file or some error wh

27、ile input the file/ DataOutputStream out2=new DataOutputStream(out); trymore=zipInput(in,bufcode);/first input 2 code if(more)curcode=bufcode0;/ out2.writeChars(dic.getString(curcode);stringOut(out,dic.getString(curcode) );elseSystem.out.println(error in the beginning.);while(more)precode=curcode;if

28、(i=0)curcode=bufcode1;i=1; elsemore=zipInput(in,bufcode);curcode=bufcode0;if(bufcode1=END)stringOut(out,dic.getString (bufcode0 );break; i=0;if(curcodedic.length()/if the prefix string can be found in the dictory/ out2.writeChars(dic.getString(curcode);stringOut(out,dic.getString(curcode) );prefix=d

29、ic.getString(precode);prefix+=(dic.getString(curcode).substring(0,1);dic.add(prefix);elseprefix=dic.getString(precode);prefix+=prefix.substring(0,1);/ out2.writeChars(prefix);stringOut(out,prefix );dic.add(prefix);/else/whilein.close ();out.close ();catch( OutDictionaryException e )System.err.printl

30、n(e);return; catch(IOException e)System.err.println(e);return; private void zipOutput(BufferedOutputStream out,short index)trybyte buf=new byte3; buf1=(byte)(index04);buf2=(byte)index1;buf1+=(byte)(index18);out.write(buf,0,3);/out put the decoding / System.out.println(index0+t+index1+t); /* short codebuf=new short2;/codebuf0=(short)(buf04);/codebuf1=(short)buf2;codebuf1=toRight

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1