⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filt_faxd.c

📁 SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多KB)
💻 C
字号:
#include "fitz-base.h"#include "fitz-stream.h"#include "filt_faxd.h"#include "filt_faxc.h"typedef enum fax_stage_e{	SNORMAL,	/* neutral state, waiting for any code */	SMAKEUP,	/* got a 1d makeup code, waiting for terminating code */	SEOL,		/* at eol, needs output buffer space */	SH1, SH2	/* in H part 1 and 2 (both makeup and terminating codes) */} fax_stage_e;/* TODO: uncompressed */typedef struct fz_faxd_s fz_faxd;struct fz_faxd_s{	fz_filter super;	int k;	int endofline;	int encodedbytealign;	int columns;	int rows;	int endofblock;	int blackis1;	int stride;	int ridx;	int bidx;	unsigned int word;	fax_stage_e stage;	int a, c, dim, eolc;	unsigned char *ref;	unsigned char *dst;};fz_error *fz_newfaxd(fz_filter **fp, fz_obj *params){	fz_obj *obj;	FZ_NEWFILTER(fz_faxd, fax, faxd);	fax->ref = nil;	fax->dst = nil;	fax->k = 0;	fax->endofline = 0;	fax->encodedbytealign = 0;	fax->columns = 1728;	fax->rows = 0;	fax->endofblock = 1;	fax->blackis1 = 0;	obj = fz_dictgets(params, "K");	if (obj) fax->k = fz_toint(obj);	obj = fz_dictgets(params, "EndOfLine");	if (obj) fax->endofline = fz_tobool(obj);	obj = fz_dictgets(params, "EncodedByteAlign");	if (obj) fax->encodedbytealign = fz_tobool(obj);	obj = fz_dictgets(params, "Columns");	if (obj) fax->columns = fz_toint(obj);	obj = fz_dictgets(params, "Rows");	if (obj) fax->rows = fz_toint(obj);	obj = fz_dictgets(params, "EndOfBlock");	if (obj) fax->endofblock = fz_tobool(obj);	obj = fz_dictgets(params, "BlackIs1");	if (obj) fax->blackis1 = fz_tobool(obj);	fax->stride = ((fax->columns - 1) >> 3) + 1;	fax->ridx = 0;	fax->bidx = 32;	fax->word = 0;	fax->stage = SNORMAL;	fax->a = -1;	fax->c = 0;	fax->dim = fax->k < 0 ? 2 : 1;	fax->eolc = 0;	fax->ref = fz_malloc(fax->stride);	if (!fax->ref)	{		fz_free(fax);		return fz_throw("outofmem: scanline buffer one");	}	fax->dst = fz_malloc(fax->stride);	if (!fax->dst)	{		fz_free(fax);		fz_free(fax->ref);		return fz_throw("outofmem: scanline buffer two");	}	memset(fax->ref, 0, fax->stride);	memset(fax->dst, 0, fax->stride);	return fz_okay;}voidfz_dropfaxd(fz_filter *p){	fz_faxd *fax = (fz_faxd*) p;	fz_free(fax->ref);	fz_free(fax->dst);}static inline void eatbits(fz_faxd *fax, int nbits){	fax->word <<= nbits;	fax->bidx += nbits;}static inline fz_error * fillbits(fz_faxd *fax, fz_buffer *in){	while (fax->bidx >= 8)	{		if (in->rp + 1 > in->wp)			return fz_ioneedin;		fax->bidx -= 8;		fax->word |= *in->rp << fax->bidx;		in->rp ++;	}	return fz_okay;}static intgetcode(fz_faxd *fax, const cfd_node *table, int initialbits){	unsigned int word = fax->word;	int tidx = word >> (32 - initialbits);	int val = table[tidx].val;	int nbits = table[tidx].nbits;	if (nbits > initialbits)	{		int mask = (1 << (32 - initialbits)) - 1;		tidx = val + ((word & mask) >> (32 - nbits));		val = table[tidx].val;		nbits = initialbits + table[tidx].nbits;	}	eatbits(fax, nbits);	return val;}/* decode one 1d code */static fz_error *dec1d(fz_faxd *fax){	int code;	if (fax->a == -1)		fax->a = 0;	if (fax->c)		code = getcode(fax, cf_black_decode, cfd_black_initial_bits);	else		code = getcode(fax, cf_white_decode, cfd_white_initial_bits);	if (code == UNCOMPRESSED)		return fz_throw("uncompressed data in faxd");	if (code < 0)		return fz_throw("negative code in 1d faxd");	if (fax->a + code > fax->columns)		return fz_throw("overflow in 1d faxd");	if (fax->c)		setbits(fax->dst, fax->a, fax->a + code);	fax->a += code;	if (code < 64)	{		fax->c = !fax->c;		fax->stage = SNORMAL;	}	else		fax->stage = SMAKEUP;	return fz_okay;}/* decode one 2d code */static fz_error *dec2d(fz_faxd *fax){	int code, b1, b2;	if (fax->stage == SH1 || fax->stage == SH2)	{		if (fax->a == -1)			fax->a = 0;		if (fax->c)			code = getcode(fax, cf_black_decode, cfd_black_initial_bits);		else			code = getcode(fax, cf_white_decode, cfd_white_initial_bits);		if (code == UNCOMPRESSED)			return fz_throw("uncompressed data in faxd");		if (code < 0)			return fz_throw("negative code in 2d faxd");		if (fax->a + code > fax->columns)			return fz_throw("overflow in 2d faxd");		if (fax->c)			setbits(fax->dst, fax->a, fax->a + code);		fax->a += code;		if (code < 64)		{			fax->c = !fax->c;			if (fax->stage == SH1)				fax->stage = SH2;			else if (fax->stage == SH2)				fax->stage = SNORMAL;		}		return fz_okay;	}	code = getcode(fax, cf_2d_decode, cfd_2d_initial_bits);	switch (code)	{		case H:			fax->stage = SH1;			break;		case P:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			b2 = findchanging(fax->ref, b1, fax->columns);			if (fax->c) setbits(fax->dst, fax->a, b2);			fax->a = b2;			break;		case V0:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1);			fax->a = b1;			fax->c = !fax->c;			break;		case VR1:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 + 1);			fax->a = b1 + 1;			fax->c = !fax->c;			break;		case VR2:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 + 2);			fax->a = b1 + 2;			fax->c = !fax->c;			break;		case VR3:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 + 3);			fax->a = b1 + 3;			fax->c = !fax->c;			break;		case VL1:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 - 1);			fax->a = b1 - 1;			fax->c = !fax->c;			break;		case VL2:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 - 2);			fax->a = b1 - 2;			fax->c = !fax->c;			break;		case VL3:			b1 = findchangingcolor(fax->ref, fax->a, fax->columns, !fax->c);			if (fax->c) setbits(fax->dst, fax->a, b1 - 3);			fax->a = b1 - 3;			fax->c = !fax->c;			break;		case UNCOMPRESSED:			return fz_throw("uncompressed data in faxd");		case ERROR:			return fz_throw("invalid code in 2d faxd");		default:			return fz_throw("invalid code in 2d faxd (%d)", code);	}	return 0;}fz_error *fz_processfaxd(fz_filter *f, fz_buffer *in, fz_buffer *out){	fz_faxd *fax = (fz_faxd*)f;	fz_error *error;	int i;	unsigned char *tmp;	if (fax->stage == SEOL)		goto eol;loop:	if (fillbits(fax, in))	{		if (in->eof)		{			if (fax->bidx > 31)			{				if (fax->a > 0)					goto eol;				goto rtc;			}		}		else		{			return fz_ioneedin;		}	}	if ((fax->word >> (32 - 12)) == 0)	{		eatbits(fax, 1);		goto loop;	}	if ((fax->word >> (32 - 12)) == 1)	{		eatbits(fax, 12);		fax->eolc ++;		if (fax->k > 0)		{			if (fax->a == -1)				fax->a = 0;			if ((fax->word >> (32 - 1)) == 1)				fax->dim = 1;			else				fax->dim = 2;			eatbits(fax, 1);		}	}	else if (fax->k > 0 && fax->a == -1)	{		fax->a = 0;		if ((fax->word >> (32 - 1)) == 1)			fax->dim = 1;		else			fax->dim = 2;		eatbits(fax, 1);	}	else if (fax->dim == 1)	{		fax->eolc = 0;		error = dec1d(fax);		if (error) return error; /* can be fz_io* or real error */	}	else if (fax->dim == 2)	{		fax->eolc = 0;		error = dec2d(fax);		if (error) return error; /* can be fz_io* or real error */	}	/* no eol check after makeup codes nor in the middle of an H code */	if (fax->stage == SMAKEUP || fax->stage == SH1 || fax->stage == SH2)		goto loop;	/* check for eol conditions */	if (fax->eolc || fax->a >= fax->columns)	{		if (fax->a > 0)			goto eol;		if (fax->eolc == (fax->k < 0 ? 2 : 6))			goto rtc;	}	goto loop;eol:	fax->stage = SEOL;	if (out->wp + fax->stride > out->ep)		return fz_ioneedout;	if (fax->blackis1)		memcpy(out->wp, fax->dst, fax->stride);	else {		unsigned char * restrict d = out->wp;		unsigned char * restrict s = fax->dst;		unsigned w = fax->stride;		for (i = 0; i < w; i++)			*d++ = *s++ ^ 0xff;	}	tmp = fax->ref;	fax->ref = fax->dst;	fax->dst = tmp;	memset(fax->dst, 0, fax->stride);	out->wp += fax->stride;	fax->stage = SNORMAL;	fax->c = 0;	fax->a = -1;	fax->ridx ++;	if (!fax->endofblock && fax->rows)	{		if (fax->ridx >= fax->rows)			goto rtc;	}	/* we have not read dim from eol, make a guess */	if (fax->k > 0 && !fax->eolc && fax->a == -1)	{		if (fax->ridx % fax->k == 0)			fax->dim = 1;		else			fax->dim = 2;	}	/* if endofline & encodedbytealign, EOLs are *not* optional */	if (fax->encodedbytealign)	{		if (fax->endofline)			eatbits(fax, (12 - fax->bidx) & 7);		else			eatbits(fax, (8 - fax->bidx) & 7);	}	goto loop;rtc:	i = (32 - fax->bidx) / 8;	while (i-- && in->rp > in->bp)		in->rp --;	return fz_iodone;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -