Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Mon Sep 16, 2019 11:54 pm
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: LZW and GIF
PostPosted: Mon Mar 02, 2009 1:52 am 
Offline

Joined: Fri Sep 30, 2005 9:12 am
Posts: 725
Location: Rockford, IL
I'm trying to write my own GIF creator, but I'm having trouble with the LZW compression. According to the GIF specification, it uses a variable length code system. When I try to implement it, however, the result turns to garbage after the point at which the code size increases. If the code size never changes during compression, the resulting gif file works perfectly. Question is, does the gif format really use a variable length code size, or am I doing something wrong?

Here is my compression code:
// CTsize is the # bits needed for the color table
// GCT is the global color table
// result holds the output bits as the picture is compressed
//
// LZW compress pixel data
// init table
for x=0 to (2^CTsize)-1
table.Append Right("00"+Hex(x),2)
next
table.Append "wx"
table.Append "yz"
EndOfInformation=UBound(table)
ClearCode=EndOfInformation-1
OriginalTableSize=UBound(table)
numbits=CTsize+1
result.Append Right("000000000000"+Bin(ClearCode),numbits)
// go thru pixel data
w=""
for y=0 to pic.Height-1
for x=0 to pic.Width-1
ch=Right("00"+Hex(GCT.IndexOf(pic.Graphics.Pixel(x,y))),2)
if table.IndexOf(w+ch)>-1 then
w=w+ch
else
result.Append Right("000000000000"+Bin(table.IndexOf(w)),NumBits)
table.Append w+ch
select case UBound(table)
case 7,15,31,63,127,255,511,1023,2047
numbits=numbits+1
case 4095
result.Append Right("000000000000"+Bin(ClearCode),numbits)
numbits=CTsize+1
ReDim table(OriginalTableSize)
end select
w=ch
end if
next
next
result.Append Right("000000000000"+Bin(table.IndexOf(w)),NumBits)
result.Append Right("000000000000"+Bin(EndOfInformation),NumBits)

_________________
RB2010r2.1 Pro on Windows 7


Top
 Profile  
Reply with quote  
 Post subject: Re: LZW and GIF
PostPosted: Mon Mar 02, 2009 7:47 am 
Offline
User avatar

Joined: Wed May 10, 2006 2:42 pm
Posts: 2985
Location: Germany
Hi,
I think I have that in my plugin already, so if you want to use a ready solution, try the GIFMBS class.

Greetings
Christian

_________________
See you in Orlando, Florida for Real World 2013
More details and registration here:
http://www.realsoftware.com/community/realworld.php


Top
 Profile  
Reply with quote  
 Post subject: Re: LZW and GIF
PostPosted: Mon Mar 02, 2009 12:37 pm 
Offline

Joined: Fri Sep 30, 2005 9:12 am
Posts: 725
Location: Rockford, IL
I'm doing this for my own enlightenment, not for any particular project.

Either gif doesn't support variable-length codes (which is contrary to the specification) or I'm doing something wrong (which is more likely). I know I can avoid this problem by sending a clear code before it gets to the point where it would want to increase the code size, but that increases the file size beyond what a full compression would be.

_________________
RB2010r2.1 Pro on Windows 7


Top
 Profile  
Reply with quote  
 Post subject: Re: LZW and GIF
PostPosted: Mon Mar 02, 2009 5:20 pm 
Offline

Joined: Fri Sep 30, 2005 9:12 am
Posts: 725
Location: Rockford, IL
Thru some experimentation I got it to work. I was increasing the code size too early (all of the examples I found on the internet showed the code size increasing at the point at which I was doing it). Just goes to show that you can't trust everything you read on the internet.

My corrected code shown below:
// CTsize is the # bits needed for the color table
// GCT is the global color table
// result holds the output bits as the picture is compressed
//
// LZW compress pixel data
// init table
for x=0 to (2^CTsize)-1
table.Append Right("00"+Hex(x),2)
next
table.Append "wx"
table.Append "yz"
EndOfInformation=UBound(table)
ClearCode=EndOfInformation-1
OriginalTableSize=UBound(table)
numbits=CTsize+1
result.Append Right("000000000000"+Bin(ClearCode),numbits)
// go thru pixel data
w=""
for y=0 to pic.Height-1
for x=0 to pic.Width-1
ch=Right("00"+Hex(GCT.IndexOf(pic.Graphics.Pixel(x,y))),2)
if table.IndexOf(w+ch)>-1 then
w=w+ch
else
result.Append Right("000000000000"+Bin(table.IndexOf(w)),NumBits)
table.Append w+ch
//
// here is where the correction is at
// had to increase each case # by one
//
select case UBound(table)
case 8,16,32,64,128,256,512,1024,2048
numbits=numbits+1
case 4096
result.Append Right("000000000000"+Bin(ClearCode),numbits)
numbits=CTsize+1
ReDim table(OriginalTableSize)
end select
w=ch
end if
next
next
result.Append Right("000000000000"+Bin(table.IndexOf(w)),NumBits)
result.Append Right("000000000000"+Bin(EndOfInformation),NumBits)

_________________
RB2010r2.1 Pro on Windows 7


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group