「javalzw解压」java解压gz

博主:adminadmin 2023-01-20 03:30:07 385

今天给各位分享javalzw解压的知识,其中也会对java解压gz进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

请问LZW的文件解压用什么软件啊

百度里搜装机必备,里面都有角解压的软件,通常的是WinRAR,好压等。下载后安装即可。

急求GIF图像的LZW压缩算法过程

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

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

1.LZW的全称是什么?

Lempel-Ziv-Welch (LZW).

2. LZW的简介和压缩原理是什么?

LZW 压缩算法是一种新颖的压缩方法,由Lemple-Ziv-Welch 三人共同创造,用他们的名字命名。它采用了一种先进的串表压缩,将每个第一次出现的串放在一个串表中,用一个数字来表示串,压缩文件只存贮数字,则不存贮串,从而使图象文件的压缩效率得到较大的提高。奇妙的是,不管是在压缩还是在解压缩的过程中都能正确的建立这个串表,压缩或解压缩完成后,这个串表又被丢弃。

LZW算法中,首先建立一个字符串表,把每一个第一次出现的字符串放入串表中,并用一个数字来表示,这个数字与此字符串在串表中的位置有关,并将这个数字存入压缩文件中,如果这个字符串再次出现时,即可用表示它的数字来代替,并将这个数字存入文件中。压缩完成后将串表丢弃。如"print" 字符串,如果在压缩时用266表示,只要再次出现,均用266表示,并将"print"字符串存入串表中,在图象解码时遇到数字266,即可从串表中查出 266所代表的字符串"print",在解压缩时,串表可以根据压缩数据重新生成。

3.在详细介绍算法之前,先列出一些与该算法相关的概念和词汇

1)'Character': 字符,一种基础数据元素,在普通文本文件中,它占用1个单独的byte,而在图像中,它却是 一种代表给定像素颜色的索引值。

2)'CharStream':数据文件中的字符流。

3)'Prefix':前缀。如这个单词的含义一样,代表着在一个字符最直接的前一个字符。一个前缀字符长度可以为0,一个prefix和一个character可以组成一个字符串(string),

4)'Suffix': 后缀,是一个字符,一个字符串可以由(A,B)来组成,A是前缀,B是后缀,当A长度为0的时候,代表Root,根

5)'Code:码,用于代表一个字符串的位置编码

6)'Entry',一个Code和它所代表的字符串(string)

4.压缩算法的简单示例,不是完全实现LZW算法,只是从最直观的角度看lzw算法的思想

对原始数据ABCCAABCDDAACCDB进行LZW压缩

原始数据中,只包括4个字符(Character),A,B,C,D,四个字符可以用一个2bit的数表示,0-A,1-B,2-C,3-D,从最直观的角度看,原始字符串存在重复字符:ABCCAABCDDAACCDB,用4代表AB,4代表CC,上面的字符串可以替代表示为:45A4CDDAA5DB,这样是不是就比原数据短了一些呢!

5.LZW算法的适用范围

为了区别代表串的值(Code)和原来的单个的数据值(String),需要使它们的数值域不重合,上面用0-3来代表A-D,那么AB就必须用大于3的数值来代替,再举另外一个例子,原来的数值范围可以用8bit来表示,那么就认为原始的数的范围是0~255,压缩程序生成的标号的范围就不能为 0~255(如果是0-255,就重复了)。只能从256开始,但是这样一来就超过了8位的表示范围了,所以必须要扩展数据的位数,至少扩展一位,但是这样不是增加了1个字符占用的空间了么?但是却可以用一个字符代表几个字符,比如原来255是8bit,但是现在用256来表示254,255两个数,还是划得来的。从这个原理可以看出LZW算法的适用范围是原始数据串最好是有大量的子串多次重复出现,重复的越多,压缩效果越好。反之则越差,可能真的不减反增了。

6.LZW算法中特殊标记

随着新的串(string)不断被发现,标号也会不断地增长,如果原数据过大,生成的标号集(string table)会越来越大,这时候操作这个集合就会产生效率问题。如何避免这个问题呢?Gif在采用lzw算法的做法是当标号集足够大的时候,就不能增大了,干脆从头开始再来,在这个位置要插入一个标号,就是清除标志CLEAR,表示从这里我重新开始构造字典,以前的所有标记作废,开始使用新的标记。

这时候又有一个问题出现,足够大是多大?这个标号集的大小为比较合适呢?理论上是标号集大小越大,则压缩比率就越高,但开销也越高。一般根据处理速度和内存空间连个因素来选定。GIF规范规定的是12位,超过12位的表达范围就推倒重来,并且GIF为了提高压缩率,采用的是变长的字长。比如说原始数据是8位,那么一开始,先加上一位再说,开始的字长就成了9位,然后开始加标号,当标号加到512时,也就是超过9为所能表达的最大数据时,也就意味着后面的标号要用10位字长才能表示了,那么从这里开始,后面的字长就是10位了。依此类推,到了2^12也就是4096时,在这里插一个清除标志,从后面开始,从9位再来。

GIF规定的清除标志CLEAR的数值是原始数据字长表示的最大值加1,如果原始数据字长是8,那么清除标志就是256,如果原始数据字长为4那么就是16。另外GIF还规定了一个结束标志END,它的值是清除标志CLEAR再加1。由于GIF规定的位数有1位(单色图),4位(16色)和8位(256色),而1位的情况下如果只扩展1位,只能表示4种状态,那么加上一个清除标志和结束标志就用完了,所以1位的情况下就必须扩充到3位。其它两种情况初始的字长就为5位和9位。此处参照了

7.用lzw算法压缩原始数据的示例分析

输入流,也就是原始的数据为:255,24,54,255,24,255,255,24,5,123,45,255,24,5,24,54..................

这个正好可以看到是gif文件中像素数组的一部分,如何对它进行压缩

因为原始数据可以用8bit来表示,故清除标志Clear=255+1 =256,结束标志为End=256+1=257,目前标号集为

0 1 2 3 .................................................................................255 CLEAR END

第一步,读取第一个字符为255,在标记表里面查找,255已经存在,我们已经认识255了,不做处理

第二步,取第二个字符,此时前缀为A,形成当前的Entry为(255,24),在标记集合不存在,我们并不认识255,24好,这次你小子来了,我就记住你,把它在标记集合中标记为258,然后输出前缀A,保留后缀24,并作为下一次的前缀(后缀变前缀)

第三步,取第三个字符为54,当前Entry(24,54),不认识,记录(24,54)为标号259,并输出24,后缀变前缀

第四部:取第四个字符255,Entry=(54,255),不认识,记录(54,255)为标号260,输出54,后缀变前缀

第五步 取第5个字符24,entry=(255,24),啊,认识你,这不是老258么,于是把字符串规约为258,并作为前缀

第六步 取第六个字符255,entry=(258,255),不认识,记录(258,255)为261,输出258,后缀变前缀

.......

一直处理到最后一个字符,

用一个表记录处理过程

CLEAR=256,END=257 第几步 前缀 后缀 Entry 认识(Y/N) 输出 标号

1 255 (,255)

2 255 24 (255,24) N 255 258

3 24 54 (24,54) N 24 259

4 54 255 (54,255) N 54 260

5 255 24 (255,24) Y

6 258 255 (258,255) N 258 261

7 255 255 (255,255) N 255 262

.....

上面这个示例有些不能完整体现,另外一个例子是

原输入数据为: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算法对其进行压缩,压缩过程用一个表来表述为:

注意原数据中只包含4个character,A,B,C,D

用两bit即可表述,根据lzw算法,首先扩展一位变为3为,Clear=2的2次方+1=4; End=4+1=5;

初始标号集因该为

0 1 2 3 4 5

A B C D Clear End

而压缩过程为:

第几步 前缀 后缀 Entry 认识(Y/N) 输出 标号

1 A (,A)

2 A B (A,B) N A 6

3 B A (B,A) N B 7

4 A B (A,B) Y

5 6 A (6,A) N 6 8

6 A B (A,B) Y

7 6 A (6,A) Y

8 8 B (8,B) N 8 9

9 B B (B,B) N B 10

10 B B (B,B) Y

11 10 A (10,A) N 10 11

12 A B (A,B) Y

.....

当进行到第12步的时候,标号集应该为

0 1 2 3 4 5 6 7 8 9 10 11

A B C D Clear End AB BA 6A 8B BB 10A

8.LZW算法的伪代码实现

1STRING = get input character

2WHILE there are still input characters DO

3 CHARACTER = get input character

4 IF STRING+CHARACTER is in the string table then

5 STRING = STRING+character

6 ELSE

7 output the code for STRING

8 add STRING+CHARACTER to the string table

9 STRING = CHARACTER

10 END of IF

11END of WHILE

12output the code for STRING

13

9.LZW算法的流程图

没有安visio,画了一个,比较难看,

----------------------------------------------------------------------------------------

using System;

using System.IO;

namespace Gif.Components

{

public class LZWEncoder

{

private static readonly int EOF = -1;

private int imgW, imgH;

private byte[] pixAry;

private int initCodeSize;

private int remaining;

private int curPixel;

// GIFCOMPR.C - GIF Image compression routines

//

// Lempel-Ziv compression based on 'compress'. GIF modifications by

// David Rowley (mgardi@watdcsu.waterloo.edu)

// General DEFINEs

static readonly int BITS = 12;

static readonly int HSIZE = 5003; // 80% occupancy

// GIF Image compression - modified 'compress'

//

// Based on: compress.c - File compression ala IEEE Computer, June 1984.

//

// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)

// Jim McKie (decvax!mcvax!jim)

// Steve Davies (decvax!vax135!petsd!peora!srd)

// Ken Turkowski (decvax!decwrl!turtlevax!ken)

// James A. Woods (decvax!ihnp4!ames!jaw)

// Joe Orost (decvax!vax135!petsd!joe)

int n_bits; // number of bits/code

int maxbits = BITS; // user settable max # bits/code

int maxcode; // maximum code, given n_bits

int maxmaxcode = 1 BITS; // should NEVER generate this code

int[] htab = new int[HSIZE];//这个是放hash的筒子,在这里面可以很快的找到1个key

int[] codetab = new int[HSIZE];

int hsize = HSIZE; // for dynamic table sizing

int free_ent = 0; // first unused entry

// block compression parameters -- after all codes are used up,

// and compression rate changes, start over.

bool clear_flg = false;

// Algorithm: use open addressing double hashing (no chaining) on the

// prefix code / next character combination. We do a variant of Knuth's

// algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime

// secondary probe. Here, the modular division first probe is gives way

// to a faster exclusive-or manipulation. Also do block compression with

// an adaptive reset, whereby the code table is cleared when the compression

// ratio decreases, but after the table fills. The variable-length output

// codes are re-sized at this point, and a special CLEAR code is generated

// for the decompressor. Late addition: construct the table according to

// file size for noticeable speed improvement on small files. Please direct

// questions about this implementation to ames!jaw.

int g_init_bits;

int ClearCode;

int EOFCode;

// output

//

// Output the given code.

// Inputs:

// code: A n_bits-bit integer. If == -1, then EOF. This assumes

// that n_bits = wordsize - 1.

// Outputs:

// Outputs code to the file.

// Assumptions:

// Chars are 8 bits long.

// Algorithm:

// Maintain a BITS character long buffer (so that 8 codes will

// fit in it exactly). Use the VAX insv instruction to insert each

// code in turn. When the buffer fills up empty it and start over.

int cur_accum = 0;

int cur_bits = 0;

int [] masks =

{

0x0000,

0x0001,

0x0003,

0x0007,

0x000F,

0x001F,

0x003F,

0x007F,

0x00FF,

0x01FF,

0x03FF,

0x07FF,

0x0FFF,

0x1FFF,

0x3FFF,

0x7FFF,

0xFFFF };

// Number of characters so far in this 'packet'

int a_count;

// Define the storage for the packet accumulator

byte[] accum = new byte[256];

//----------------------------------------------------------------------------

public LZWEncoder(int width, int height, byte[] pixels, int color_depth)

{

imgW = width;

imgH = height;

pixAry = pixels;

initCodeSize = Math.Max(2, color_depth);

}

// Add a character to the end of the current packet, and if it is 254

// characters, flush the packet to disk.

void Add(byte c, Stream outs)

{

accum[a_count++] = c;

if (a_count = 254)

Flush(outs);

}

// Clear out the hash table

// table clear for block compress

void ClearTable(Stream outs)

{

ResetCodeTable(hsize);

free_ent = ClearCode + 2;

clear_flg = true;

Output(ClearCode, outs);

}

// reset code table

// 全部初始化为-1

void ResetCodeTable(int hsize)

{

for (int i = 0; i hsize; ++i)

htab = -1;

}

void Compress(int init_bits, Stream outs)

{

int fcode;

int i /* = 0 */;

int c;

int ent;

int disp;

int hsize_reg;

int hshift;

// Set up the globals: g_init_bits - initial number of bits

//原始数据的字长,在gif文件中,原始数据的字长可以为1(单色图),4(16色),和8(256色)

//开始的时候先加上1

//但是当原始数据长度为1的时候,开始为3

//因此原始长度1-3,4-5,8-9

//?为何原始数据字长为1的时候,开始长度为3呢??

//如果+1=2,只能表示四种状态,加上clearcode和endcode就用完了。所以必须扩展到3

g_init_bits = init_bits;

// Set up the necessary values

//是否需要加清除标志

//GIF为了提高压缩率,采用的是变长的字长(VCL)。比如说原始数据是8位,那么开始先加上1位(8+1=9)

//当标号到2^9=512的时候,超过了当前长度9所能表现的最大值,此时后面的标号就必须用10位来表示

//以此类推,当标号到2^12的时候,因为最大为12,不能继续扩展了,需要在2^12=4096的位置上插入一个ClearCode,表示从这往后,从9位重新再来了

clear_flg = false;

n_bits = g_init_bits;

//获得n位数能表述的最大值(gif图像中开始一般为3,5,9,故maxcode一般为7,31,511)

maxcode = MaxCode(n_bits);

//表示从这里我重新开始构造字典字典了,以前的所有标记作废,

//开始使用新的标记。这个标号集的大小多少比较合适呢?据说理论上是越大压缩率越高(我个人感觉太大了也不见得就好),

//不过处理的开销也呈指数增长

//gif规定,clearcode的值为原始数据最大字长所能表达的数值+1;比如原始数据长度为8,则clearcode=1(9-1)=256

ClearCode = 1 (init_bits - 1);

//结束标志为clearcode+1

EOFCode = ClearCode + 1;

//这个是解除结束的

free_ent = ClearCode + 2;

//清楚数量

a_count = 0; // clear packet

//从图像中获得下一个像素

ent = NextPixel();

hshift = 0;

for (fcode = hsize; fcode 65536; fcode *= 2)

++hshift;

//设置hash码范围

hshift = 8 - hshift; // set hash code range bound

hsize_reg = hsize;

//清除固定大小的hash表,用于存储标记,这个相当于字典

ResetCodeTable(hsize_reg); // clear hash table

Output(ClearCode, outs);

outer_loop : while ((c = NextPixel()) != EOF)

{

fcode = (c maxbits) + ent;

i = (c hshift) ^ ent; // xor hashing

//嘿嘿,小样,又来了,我认识你

if (htab == fcode)

{

ent = codetab;

continue;

}

//这小子,新来的

else if (htab = 0) // non-empty slot

{

disp = hsize_reg - i; // secondary hash (after G. Knott)

if (i == 0)

disp = 1;

do

{

if ((i -= disp) 0)

i += hsize_reg;

if (htab == fcode)

{

ent = codetab;

goto outer_loop;

}

} while (htab = 0);

}

Output(ent, outs);

//从这里可以看出,ent就是前缀(prefix),而当前正在处理的字符标志就是后缀(suffix)

ent = c;

//判断终止结束符是否超过当前位数所能表述的范围

if (free_ent maxmaxcode)

{

//如果没有超

codetab = free_ent++; // code - hashtable

//hash表里面建立相应索引

htab = fcode;

}

else

//说明超过了当前所能表述的范围,清空字典,重新再来

ClearTable(outs);

}

// Put out the final code.

Output(ent, outs);

Output(EOFCode, outs);

}

//----------------------------------------------------------------------------

public void Encode( Stream os)

{

os.WriteByte( Convert.ToByte( initCodeSize) ); // write "initial code size" byte

//这个图像包含多少个像素

remaining = imgW * imgH; // reset navigation variables

//当前处理的像素索引

curPixel = 0;

Compress(initCodeSize + 1, os); // compress and write the pixel data

os.WriteByte(0); // write block terminator

}

// Flush the packet to disk, and reset the accumulator

void Flush(Stream outs)

{

if (a_count 0)

{

outs.WriteByte( Convert.ToByte( a_count ));

outs.Write(accum, 0, a_count);

a_count = 0;

}

}

/// summary

/// 获得n位数所能表达的最大数值

/// /summary

/// param name="n_bits"位数,一般情况下n_bits = 9/param

/// returns最大值,例如n_bits=8,则返回值就为2^8-1=255/returns

int MaxCode(int n_bits)

{

return (1 n_bits) - 1;

}

//----------------------------------------------------------------------------

// Return the next pixel from the image

//----------------------------------------------------------------------------

/// summary

/// 从图像中获得下一个像素

/// /summary

/// returns/returns

private int NextPixel()

{

//还剩多少个像素没有处理

//如果没有了,返回结束标志

if (remaining == 0)

return EOF;

//否则处理下一个,并将未处理像素数目-1

--remaining;

//当前处理的像素

int temp = curPixel + 1;

//如果当前处理像素在像素范围之内

if ( temp pixAry.GetUpperBound( 0 ))

{

//下一个像素

byte pix = pixAry[curPixel++];

return pix 0xff;

}

return 0xff;

}

/// summary

/// 输出字到输出流

/// /summary

/// param name="code"要输出的字/param

/// param name="outs"输出流/param

void Output(int code, Stream outs)

{

//得到当前标志位所能表示的最大标志值

cur_accum = masks[cur_bits];

if (cur_bits 0)

cur_accum |= (code cur_bits);

else

//如果标志位为0,就将当前标号为输入流

cur_accum = code;

//当前能标志的最大字长度(9-10-11-12-9-10。。。。。。。)

cur_bits += n_bits;

//如果当前最大长度大于8

while (cur_bits = 8)

{

//向流中输出一个字节

Add((byte) (cur_accum 0xff), outs);

//将当前标号右移8位

cur_accum = 8;

cur_bits -= 8;

}

// If the next entry is going to be too big for the code size,

// then increase it, if possible.

if (free_ent maxcode || clear_flg)

{

if (clear_flg)

{

maxcode = MaxCode(n_bits = g_init_bits);

clear_flg = false;

}

else

{

++n_bits;

if (n_bits == maxbits)

maxcode = maxmaxcode;

else

maxcode = MaxCode(n_bits);

}

}

if (code == EOFCode)

{

// At EOF, write the rest of the buffer.

while (cur_bits 0)

{

Add((byte) (cur_accum 0xff), outs);

cur_accum = 8;

cur_bits -= 8;

}

Flush(outs);

}

}

}

}

“LZW压缩格式”急需各位高手讲解下!?

LZW压缩格式

LZW(Lempel-Ziv Welch)表示一种算法,它能把大文件转变成更适合于网页使用的较小文件。实现方法是将一系列符号压缩成单个符号乘以该符号的出现次数。LZW压缩格式叫做“无陨”数据压缩格式,即尽管数据得到压缩,但解压后的图像看上去同原文件完全一样。

求LZW压缩,解压算法详解流程

LZW压缩算法

LZW算法流程图

LZW算法基于转换串表(字典)T,将输入字符串映射成定长(通常为12位)的码字。在12位4096种可能的代码中,256个代表单字符,剩下3840给出现的字符串。

LZW字典中的字符串具有前缀性,即 ωK∈T=;ω

T。

LZW算法流程:

步骤1: 开始时的词典包含所有可能的根(Root),而当前前缀P是空的;

步骤2: 当前字符(C) :=字符流中的下一个字符;

步骤3: 判断缀-符串P+C是否在词典中

(1) 如果“是”:P := P+C // (用C扩展P) ;

(2) 如果“否”

① 把代表当前前缀P的码字输出到码字流;

② 把缀-符串P+C添加到词典;

③ 令P := C //(现在的P仅包含一个字符C);

步骤4: 判断码字流中是否还有码字要译

(1) 如果“是”,就返回到步骤2;

(2) 如果“否”

① 把代表当前前缀P的码字输出到码字流;

② 结束。

LZW解压算法

具体解压步骤如下:

(1)译码开始时Dictionary包含所有的根。

(2)读入在编码数据流中的第一个码字 cW(它表示一个Root)。

(3)输出String.cW到字符数据流Charstream。

(4)使pW=cW 。

(5)读入编码数 据流 的下一个码字cW 。

(6)目前在字典中有String.cW吗?

YES:1)将String.cW输出给字符数据流;

2)使P=String.pW;

3)使C=String.cW的第一个字符;

4)将字符 串P+C添 加进Dictionray。

NO :1)使P=String.pW ;

2)使C=String.pW的第一个字符;

3)将字符串P+C输出到字符数据流并将其添加进Dictionray(现在它与cW相一致)。

(7)在编码数据 流中还有Codeword吗?

YES:返回(4)继 续进行 译码 。

NO:结束译码 。

什么是"LZW 压缩"?

首先是lzw的概念 LZW(Lempel Ziv Welch)压缩编码是一种先进的数据压缩技术,属于无损压缩编码,该编码主要用于图像数据的压缩。对于简单图像和平滑且噪声小的信号源具有较高的压缩比,并且有较高的压缩和解压缩速度。

一个较大的文件经压缩后,产生了另一个较小容量的文件。而这个较小容量的文件,我们就叫它是这些较大容量的(可能一个或一个以上的文件)的压缩文件。而压缩此文件的过程称为文件压缩。

网络上有两种常见的压缩格式:一种是Zip,另一种是EXE。其中Zip的压缩文件可以通过WinZip这套解压缩工具进行解压缩,而EXE则是属于自解压文件,只要用鼠标双击这类下载后的文件图标(若您的Windows98属于Web风格,则只需按一下),便可以自动解压缩。

因为EXE文件内含解压缩程序,因此会比Zip略大一些。若想充分考虑到文件容量的大小,其实Zip是一个较佳的选择。

压缩技术可分为通用无损数据压缩与有损压缩两大类,但不管是采用何种技术模型,其本质内容都是一样的,即都是通过某种特殊的编码方式将数据信息中存在的重复度、冗余度有效地降低,从而达到数据压缩的目的。

javalzw解压的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java解压gz、javalzw解压的信息别忘了在本站进行查找喔。