This is giflzw.c in view mode; [Download] [Up]
#include <stdio.h>
#include "gif.h"
#define MAX_LWZ_BITS 12
static int fresh = NO;
static int code_size, set_code_size;
static int max_code, max_code_size;
static int firstcode, oldcode;
static int clear_code, end_code;
static int *sp;
static int table[2][(1<< MAX_LWZ_BITS)];
#define MAXSTACKSZ ((1<<(MAX_LWZ_BITS))*2 + 2)
static int stack[MAXSTACKSZ];
static unsigned char buffer[280];
static int curbit, lastbit, done, last_byte;
static void
initGetCode(void)
{
curbit = 0;
lastbit = 0;
done = NO;
}
static int
GetCode(FILE *fd, int code_size)
{
int i, j, ret;
unsigned char count;
if ( (curbit+code_size) >= lastbit) {
if (done)
return -1;
buffer[0] = buffer[last_byte-2];
buffer[1] = buffer[last_byte-1];
if ((count = GetDataBlock(fd, &buffer[2])) == 0)
done = YES;
last_byte = 2 + count;
curbit = (curbit - lastbit) + 16;
lastbit = (2+count)*8 ;
}
ret = 0;
for (i = curbit, j = 0; j < code_size; ++i, ++j)
ret |= ((buffer[ i / 8 ] & (1 << (i % 8))) != 0) << j;
curbit += code_size;
return ret;
}
static int ZeroDataBlock = NO;
int GetDataBlock(FILE *fd, unsigned char *buf)
{
int count;
if ((count = getc(fd)) == EOF)
return -1;
ZeroDataBlock = count == 0;
if ((count != 0) && (! ReadOK(fd, buf, count)))
return -1;
buf[count] = 0;
return count;
}
int initGifLZW(FILE *fp)
{
int i;
if ((set_code_size = getc(fp)) == EOF)
return EOF;
code_size = set_code_size+1;
clear_code = 1 << set_code_size ;
end_code = clear_code + 1;
max_code_size = 2*clear_code;
max_code = clear_code+2;
fresh = YES;
sp = stack;
initGetCode();
for (i = 0; i < clear_code; ++i) {
table[0][i] = 0;
table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
table[0][i] = table[1][0] = 0;
return 0;
}
int LWZReadByte(FILE *fd)
{
register int i;
int code, incode;
if (fresh) {
fresh = NO;
do {
firstcode = oldcode = GetCode(fd, code_size);
} while (firstcode == clear_code);
return firstcode;
}
if (sp > stack)
return *--sp;
while ((code = GetCode(fd, code_size)) >= 0) {
if (code == clear_code) {
for (i = 0; i < clear_code; ++i) {
table[0][i] = 0;
table[1][i] = i;
}
for (; i < (1<<MAX_LWZ_BITS); ++i)
table[0][i] = table[1][i] = 0;
code_size = set_code_size+1;
max_code_size = 2*clear_code;
max_code = clear_code+2;
sp = stack;
firstcode = oldcode = GetCode(fd, code_size);
return firstcode;
}
if (code == end_code) {
int count;
unsigned char buf[260];
if (ZeroDataBlock)
return -2;
while ((count = GetDataBlock(fd, buf)) > 0)
;
return -2;
}
incode = code;
if (code >= max_code) {
*sp++ = firstcode;
code = oldcode;
}
while (code >= clear_code) {
if (sp >= &stack[MAXSTACKSZ-1])
return *--sp; /* ERROR */
*sp++ = table[1][code];
code = table[0][code];
}
*sp++ = firstcode = table[1][code];
if ((code = max_code) < (1<<MAX_LWZ_BITS)) {
table[0][code] = oldcode;
table[1][code] = firstcode;
++max_code;
if ((max_code >= max_code_size) &&
(max_code_size < (1<<MAX_LWZ_BITS))) {
max_code_size *= 2;
++code_size;
}
}
oldcode = incode;
if (sp > stack)
return *--sp;
}
return code;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.