Java & Swing实现对GIF图像的解析和显示。
有三部分内容: 1 是gif文件解析; 2 是 图像数据解码; 3 是GUI端显示;仅贴出第2部分图像数据解码, 解码也有三部分,1 是基于位的code获取; 2是字典项的维护,3是转换为实际像素。
// 字典项分为三种: Value,Clear, End
abstract class Code { }
class ValueCode extends Code {
private final int[] prev; // 前缀
private final int[] code; // 后缀
private final int[] val; // 前缀+后缀 utils
public ValueCode(int[] code) {
this(null, code);
}
public ValueCode(int[] prev, int[] code) {
this.prev = prev;
this.code = code;
if (prev == null)
val = code;
else if (code == null)
val = prev;
else {
val = new int[prev.length + code.length];
System.arraycopy(prev, 0, val, 0, prev.length);
System.arraycopy(code, 0, val, prev.length, code.length);
}
}
public int[] First() {
return new int[] { val[0] };
}
。。。。。。
}
class ClearCode extends Code {
。。。。。。
}
class EndCode extends Code {
。。。。。。
}
字典维护类:
class Dictionary {
private Vector<Code> table = new Vector<>();
public Dictionary(int[] bs) {
for (int b : bs)
addValueCode(new ValueCode(null, new int[] {b}));
table.add(new ClearCode());
table.add(new EndCode());
}
public Dictionary(int bits) {
int len = 1 << bits;
for (int i=0; i< len ; i++)
addValueCode(new ValueCode(null, new int[] { i }));
table.add(new ClearCode());
table.add(new EndCode());
}
public int getBitLen() {
int max = -1;
int len = table.size();
for (int i=0; i<12; i++) {
if ( (len & 1) == 1)
max = i;
len = (len >> 1);
}
return max + 1;
}
。。。。。。
}
实现解压缩:
static int[] uncompress(final Dictionary dict , int[] data) {
IntArrayBuffer output = new IntArrayBuffer();
int ByteOffset = 0;
int thisBitsOffset = 0;
ValueCode lastValue = null;
while (true) {
int code;
// if (ByteOffset >=data.length )
// break;
int BIT_LEN = dict.getBitLen();
{
if (ByteOffset == 1125)
System.out.println();
int b = data[ ByteOffset ];
if (thisBitsOffset + BIT_LEN <= 8) {
code = GetBitsFromRight(b, thisBitsOffset, BIT_LEN);
thisBitsOffset = thisBitsOffset + BIT_LEN;
if (thisBitsOffset % 8 == 0) {
thisBitsOffset = 0;
ByteOffset = ByteOffset + 1;
}
}
else {
int rBitLen = 8 - thisBitsOffset;
code = GetBitsFromRight(b, thisBitsOffset, rBitLen);
// if (ByteOffset + 1 >= data.length)
// break;
int lBitLen = BIT_LEN - rBitLen;
int llBitLen = -1;
if (lBitLen != 0) {
b = data[ ++ByteOffset ];
int b2 = GetBitsFromRight(b, 0 , lBitLen > 8 ? 8 : lBitLen);
code = (b2 << rBitLen) | code;
llBitLen = lBitLen - 8;
}
if (llBitLen > 0) {
b = data[ ++ByteOffset ];
int b2 = GetBitsFromRight(b, 0 , llBitLen);
code = (b2 << (8+lBitLen) ) | code;
}
thisBitsOffset = (thisBitsOffset + BIT_LEN) % 8;
if (thisBitsOffset % 8 == 0) {
thisBitsOffset = 0;
ByteOffset = ByteOffset + 1;
}
}
}
Code _value = dict.getCode(code);
if (_value == null || _value instanceof ValueCode) {
ValueCode value = (ValueCode) _value ;
if (value == null) {
if (lastValue != null) {
value = new ValueCode(lastValue.getValue() , lastValue.First());
dict.addValueCode(value);
}
}
else {
if (lastValue != null) {
ValueCode vv = new ValueCode(lastValue.getValue(), value.First());
dict.addValueCode(vv);
}
}
output.Write(value.getValue());
lastValue = value;
}
else if (_value instanceof ClearCode e) {
dict.clear();
}
else if (_value instanceof EndCode) {
break ;
}
}
return output.GetInts();
}
效果如下: