Sigrid Solveig Haflínudóttiradd TODO to the readmec626c595 years agoHistory
166 lines · 2.4 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "pdf.h" /* 7.4.4 LZWDecode filter */ typedef struct Pt Pt;typedef struct Tb Tb; struct Pt {	int o, sz;}; struct Tb {	Pt *pt;	int npt; 	uchar *p;	int max;	int off; 	Pt pr;}; static voidtbclean(Tb *tb){	int i; 	tb->off = 256;	tb->npt = 258; 	if(tb->p == nil){		tb->max = 1024;		tb->p = malloc(tb->max);	}	if(tb->pt == nil){		tb->pt = malloc(sizeof(Pt)*4096);		for(i = 0; i < 256; i++){			tb->p[i] = i;			tb->pt[i].o = i;			tb->pt[i].sz = 1;		}	}	memset(tb->pt+tb->npt, 0, sizeof(Pt)*(4096-tb->npt));} static inttbputc(Tb *tb, int c, Buffer *o){	uchar *d;	Pt *pt;	int n; 	if(tb->pt == nil)		tbclean(tb); 	/* firt, make sure things will fit in */	if(tb->max <= tb->off*2){		tb->max = tb->off*4;		tb->p = realloc(tb->p, tb->max);	} 	pt = &tb->pt[c];	if(pt->sz > 0){		d = tb->p + pt->o;		n = pt->sz; 		if(tb->pr.sz > 0){			/* have prefix - insert another point */			pt = &tb->pt[tb->npt++];			pt->o = tb->off;			pt->sz = tb->pr.sz + 1;			memmove(tb->p + pt->o, tb->p + tb->pr.o, tb->pr.sz);			tb->p[pt->o + pt->sz - 1] = d[0];			tb->off += pt->sz;		} 		/* update prefix */		tb->pr.o = d - tb->p;		tb->pr.sz = n;	}else{		pt = &tb->pt[tb->npt++];		pt->o = tb->off;		pt->sz = tb->pr.sz + 1;		memmove(tb->p + pt->o, tb->p + tb->pr.o, tb->pr.sz);		tb->p[pt->o + pt->sz - 1] = tb->p[tb->pr.o];		tb->off += pt->sz; 		tb->pr.o = pt->o;		tb->pr.sz = pt->sz; 		d = tb->p + pt->o;		n = pt->sz;	} 	bufput(o, d, n); 	if(tb->npt < 511)		return 9;	if(tb->npt < 1023)		return 10;	if(tb->npt < 2047)		return 11;	if(tb->npt < 4097)		return 12; 	return -1;} static voidtbfree(Tb *tb){	free(tb->p);	free(tb->pt);	memset(tb, 0, sizeof(*tb));} static intflreadall(void *aux, Buffer *bi, Buffer *bo){	int i, j, x, insz, width, w;	uchar *in;	Tb tb; 	memset(&tb, 0, sizeof(tb));	in = bufdata(bi, &insz);	width = 9;	x = 0;	for(i = w = 0, j = 7; i < insz; j--){		x = x<<1 | ((in[i] & (1<<j)) >> j);		if(j < 1){			i++;			j = 8;		} 		if(++w == width){			if(x == 257) /* EOD */				break; 			if(x == 256){ /* CLEAR */				tbclean(&tb);				width = 9;			}else if((width = tbputc(&tb, x, bo)) < 0){				werrstr("points overflow");				tbfree(&tb);				return -1;			} 			w = 0;			x = 0;		}	} 	tbfree(&tb);	bi->off = bi->sz; 	return unpredict(aux, bo);} Filter filterLZW = {	.name = "LZWDecode",	.readall = flreadall,	.open = flopenpredict,	.close = flclosepredict,};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t