Sigrid Solveig Haflínudóttirlzw and flate filters: use common predict logicef5d7bc5 years agoHistory
128 lines · 2.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "pdf.h" struct PredictParms {	int predictor;	int columns;}; static uchar paeth(uchar a, uchar b, uchar c){	int p, pa, pb, pc; 	p = a + b - c;	pa = abs(p - a);	pb = abs(p - b);	pc = abs(p - c); 	if(pa <= pb && pa <= pc)		return a;	return pb <= pc ? b : c;} static intpngunpredict(int pred, uchar *buf, uchar *up, int len){	int i; 	switch(pred){	case 0: /* None */		break; 	case 1: /* Sub */		for(i = 1; i < len; ++i)			buf[i] += buf[i-1];		break; 	case 2: /* Up */		for(i = 0; i < len; ++i)			buf[i] += up[i];		break; 	case 3: /* Average */		buf[0] += up[0]/2;		for(i = 1; i < len; ++i)			buf[i] += (buf[i-1]+up[i])/2;		break; 	case 4: /* Paeth */		buf[0] += paeth(0, up[0], 0);		for(i = 0; i < len; ++i)			buf[i] += paeth(buf[i-1], up[i], up[i-1]);		break; 	/* FIXME 5 optimum??? */ 	default:		werrstr("unsupported predictor %d", pred);		return -1;	} 	return 0;} intunpredict(PredictParms *pp, Buffer *bo){	uchar *x, *y, *zero;	int i, r, rows, n; 	if(pp->predictor < 10 || pp->columns < 1)		return 0; 	n = pp->columns + 1;	rows = bo->sz/n;	x = bo->b;	y = bo->b;	zero = mallocz(pp->columns, 1);	for(i = r = 0; i < rows && r == 0; i++, x += n, y += n)		r = pngunpredict(x[0], x+1, i < 1 ? zero : y+1-n, pp->columns);	free(zero); 	if(r != 0)		return r; 	x = bo->b;	y = bo->b+1;	for(i = 0; i < rows; i++, x += pp->columns, y += n)		memmove(x, y, pp->columns);	bo->sz -= rows; 	return r;} intflopenpredict(Filter *f, Object *o){	Object *parms;	PredictParms *pp;	int predictor, columns; 	parms = dictget(o, "DecodeParms");	predictor = dictint(parms, "Predictor");	columns = dictint(parms, "Columns");	if((predictor >= 2 && predictor < 10) || predictor >= 15){		werrstr("unsupported flate predictor %d", predictor);		return -1;	}	if(predictor >= 10 && predictor <= 15 && columns < 1){		werrstr("invalid columns %d for predictor %d", columns, predictor);		return -1;	} 	if((pp = malloc(sizeof(*pp))) == nil)		return -1;	pp->predictor = predictor;	pp->columns = columns;	f->aux = pp; 	return 0;} voidflclosepredict(Filter *f){	free(f->aux);}

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