Original Post
I guess I posed this in the wrong forum the first time, so here goes: I am using GIF/LZ decoding software located at http://www.cplusplus.com/src/ (GIFView). The code is quite fast, but in some rare cases it introduces some artifacts into the decoded bmp. In my case it is a bitmap font (just some letters in a wide bitmap with alot of transparent space), and some letters have extra black pixels attached or are missing pixels. Is there any way to post pictures here? (there is a discussion about this over at The Code Project): http://tinyurl.com/fyrob I'm stuck using GIFs and don't really want to recode it. But I cannot seems to narrow down where the problem is. Any assistance would be greatly appreciated! thanks --------------------------------------------------------------
int LZWDecoder (unsigned char * bufIn, unsigned char * bufOut,
short InitCodeSize, int AlignedWidth,
int Width, int Height, const int Interlace)
{
int n;
int row=0,col=0; // used to point output if Interlaced
int nPixels, maxPixels; // Output pixel counter
short CodeSize; // Current CodeSize (size in bits of codes)
short ClearCode; // Clear code : resets decompressor
short EndCode; // End code : marks end of information
long whichBit; // Index of next bit in bufIn
long LongCode; // Temp. var. from which Code is retrieved
short Code; // Code extracted
short PrevCode; // Previous Code
short OutCode; // Code to output
// Translation Table:
int Prefix[4097]; // Prefix: index of another Code
int Suffix[4097]; // Suffix: terminating character
short FirstEntry; // Index of first free entry in table
short NextEntry; // Index of next free entry in table
int OutStack[4097]; // Output buffer
int OutIndex; // Characters in OutStack
int RowOffset; // Offset in output buffer for current row
// Set up values that depend on InitCodeSize Parameter.
CodeSize = InitCodeSize+1;
ClearCode = (1 << InitCodeSize);
EndCode = ClearCode + 1;
NextEntry = FirstEntry = ClearCode + 2;
whichBit=0;
nPixels = 0;
maxPixels = Width*Height;
RowOffset =0;
while (nPixels<maxPixels) {
OutIndex = 0; // Reset Output Stack
// GET NEXT CODE FROM bufIn:
// LZW compression uses code items longer than a single byte.
// For GIF Files, code sizes are variable between 9 and 12 bits
// That's why we must read data (Code) this way:
LongCode=*((long*)(bufIn+(whichBit/8))); // Get some bytes from bufIn
LongCode>>=(whichBit&7); // Discard too low bits
Code =(LongCode & ((1<<CodeSize)-1) ); // Discard too high bits
whichBit += CodeSize; // Increase Bit Offset
// SWITCH, DIFFERENT POSIBILITIES FOR CODE:
if (Code == EndCode) // END CODE
break; // Exit LZW Decompression loop
if (Code == ClearCode) { // CLEAR CODE:
CodeSize = InitCodeSize+1; // Reset CodeSize
NextEntry = FirstEntry; // Reset Translation Table
PrevCode=Code; // Prevent next to be added to table.
continue; // restart, to get another code
}
if (Code < NextEntry) // CODE IS IN TABLE
OutCode = Code; // Set code to output.
else { // CODE IS NOT IN TABLE:
OutIndex++; // Keep "first" character of previous output.
OutCode = PrevCode; // Set PrevCode to be output
}
// EXPAND OutCode IN OutStack
// - Elements up to FirstEntry are Raw-Codes and are not expanded
// - Table Prefices contain indexes to other codes
// - Table Suffices contain the raw codes to be output
while (OutCode >= FirstEntry)
{
if (OutIndex >= 4096 || OutCode >=4096)
{
return 0;
}
OutStack[OutIndex++] = Suffix[OutCode]; // Add suffix to Output Stack
OutCode = Prefix[OutCode]; // Loop with preffix
}
// NOW OutCode IS A RAW CODE, ADD IT TO OUTPUT STACK.
if (OutIndex >= 4096)
{
return 0;
}
OutStack[OutIndex++] = OutCode;
// ADD NEW ENTRY TO TABLE (PrevCode + OutCode)
// (EXCEPT IF PREVIOUS CODE WAS A CLEARCODE)
if (PrevCode!=ClearCode) {
Prefix[NextEntry] = PrevCode;
Suffix[NextEntry] = OutCode;
NextEntry++;
// Prevent Translation table overflow:
if (NextEntry>4096)
{
return 0;
}
// INCREASE CodeSize IF NextEntry IS INVALID WITH CURRENT CodeSize
if (NextEntry >= (1<<CodeSize))
{
if (CodeSize < 12)
{
CodeSize++;
}
else
{
// Do nothing. Maybe next is Clear Code.
int iTemp = 9999;
}
}
}
PrevCode = Code;
// Avoid the possibility of overflow on 'bufOut'.
if (nPixels + OutIndex > maxPixels) OutIndex = maxPixels-nPixels;
// OUTPUT OutStack (LAST-IN FIRST-OUT ORDER)
for (n=OutIndex-1; n>=0; n--)
{
if (col==Width) // Check if new row.
{
if (Interlace) { // If interlaced::
if ((row&7)==0) {row+=8; if (row>=Height) row=4;}
else if ((row&3)==0) {row+=8; if (row>=Height) row=2;}
else if ((row&1)==0) {row+=4; if (row>=Height) row=1;}
else row+=2;
}
else // If not interlaced:
row++;
RowOffset=row*AlignedWidth; // Set new row offset
col=0;
}
bufOut[RowOffset+col]=OutStack[n]; // Write output
col++; nPixels++; // Increase counters.
}
} // while (main decompressor loop)
return whichBit;
}