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.