需要帮助解压缩GIF栅格数据

时间:2014-08-17 01:22:42

标签: gif compression lzw

我有一个10x10 gif,由4种颜色组成,白色,红色,蓝色,黑色。我已经解析了下面的gif数据

4749 4638 3961                      <-- header

0a00 0a00 9100 00                   <-- lsd (pb 91 = 1001 0001) nColors = 4, bytes = 12

ffffff ff0000 0000ff 000000         <-- global color table
                                    #0  FF FF FF
                                    #1  FF 00 00
                                    #2  00 00 FF
                                    #3  00 00 00

21f9 04(00) (0000) (00)00           <-- graphics control extension 
                                    (00) = pb (000 reserved 000 disposal method 0 user input flag 0 transparent color flag) 
                                    (0000) = delay time                     
                                    (00) = transparent color index

2c 0000 0000 0a00 0a00 00           <-- image descriptor

02 16                               <-- (image data - 02 = lzw min code size, 0x16 size of image (bytes))
8c2d 9987 2a1c dc33 a002 75ec 95fa a8de 608c 0491 4c01 00   <-- image block
3b  

好的,我们上面有我们的图像数据(标记为图像块),我正在尝试将其解压缩,以便恢复原始图像。我的理解是你从lzwmincodesize + 1开始从左到右读取字节,从右到左读取数据(2 + 1位=每次3位)。

这是我正在关注的解压缩算法

Initialize code table
let CODE be the first code in the code stream
output {CODE} to index stream
<LOOP POINT>
let CODE be the next code in the code stream
is CODE in the code table?
Yes:
    output {CODE} to index stream
    let K be the first index in {CODE}
    add {CODE-1}+K to the code table
No:
    let K be the first index of {CODE-1}
    output {CODE-1}+K to index stream
    add {CODE-1}+K to code table
return to LOOP POINT

我正在逐步完成解压缩算法,这是我到目前为止所提出的...(从前3字节代码开始)

Global Color Table
000 FF FF FF
001 FF 00 00
010 00 00 FF
011 00 00 00
100 CLEAR
101 End of Data

 3  2   1   6  5   4      8   7    
10|001|100  0|010|110|1  100|110|01

last        current     output      cindex      exists      dictionary      value
            100                     4                                       CLEAR
100         001         001         1           y                           RED
001         110         001 001     6           n           +001 001        RED RED
001 001     110         001 001     6           y           +001 001 001    RED RED
001 001     010         010         2           y           +001 001 010    BLUE
010         010         010         2           y           +010 010        BLUE
010         110         001 001     6           y           +010 001 001    RED RED
001 001     100                     4                                       CLEAR
100         111         111         7 ???? <--- (what do I do here)?

我应该获得5个红色值,然后是前10个像素的5个蓝色值,但是你可以看到它解码5个红色然后2个蓝色然后2个红色。谁能指出我在这里做错了什么?

由于

1 个答案:

答案 0 :(得分:1)

您的错误来自于错过代码大小的增加。以下是代码,“nextcode”值和当前代码大小:

Code read from bitstream:    100, 001, 110, 110, 0010, 1001
internal 'Next' code value:  110, 110, 110, 111, 1000, 1001
current code size:             3,   3,   3,   3,    4,    4

解码循环中缺少的逻辑是您需要维护一个“nextcode”变量,该变量告诉您​​在表中插入代码的位置以及何时增加代码大小。它从值“clearcode + 2”开始,并在从比特流读取每个代码后(在第一个非CC值之后)增加。逻辑基本上是这样的:

clear_dictionary:
clearcode = 1<<codestart;
codesize = codestart+1;
nextcode = clearcode + 2;
nextlimit = 1<<(codesize+1);
oldcode = -1;
mainloop:
while (!done)
{
code = getCode();
if (code == clearcode)
   goto clear_dictionary;
if (oldcode == -1)
{
   write_code_to_output(code);
}
else
{
   <LZW logic>
   nextcode++;
   if (nextcode >= nextlimit)
   {
      nextlimit <<= 1;
      codesize++;
   }
}
oldcode = code;
} // while !done
相关问题