filt_lzwd.c.svn-base

来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 255 行

SVN-BASE
255
字号
#include "fitz-base.h"#include "fitz-stream.h"/* TODO: error checking */enum{	MINBITS = 9,	MAXBITS = 12,	NUMCODES = (1 << MAXBITS),	LZW_CLEAR = 256,	LZW_EOD = 257,	LZW_FIRST = 258};typedef struct lzw_code_s lzw_code;struct lzw_code_s{	int prev;					/* prev code (in string) */	unsigned short length;		/* string len, including this token */	unsigned char value;		/* data value */	unsigned char firstchar;	/* first token of string */};typedef struct fz_lzwd_s fz_lzwd;struct fz_lzwd_s{	fz_filter super;	int earlychange;	unsigned int word;		/* bits loaded from data */	int bidx;	int resume;				/* resume output of code from needout */	int codebits;			/* num bits/code */	int code;				/* current code */	int oldcode;			/* previously recognized code */	int nextcode;			/* next free entry */	lzw_code table[NUMCODES];};fz_error *fz_newlzwd(fz_filter **fp, fz_obj *params){	int i;	FZ_NEWFILTER(fz_lzwd, lzw, lzwd);	lzw->earlychange = 0;	if (params)	{		fz_obj *obj;		obj = fz_dictgets(params, "EarlyChange");		if (obj) lzw->earlychange = fz_toint(obj) != 0;	}	lzw->bidx = 32;	lzw->word = 0;	for (i = 0; i < 256; i++)	{		lzw->table[i].value = i;		lzw->table[i].firstchar = i;		lzw->table[i].length = 1;		lzw->table[i].prev = -1;	}	for (i = 256; i < NUMCODES; i++)	{		lzw->table[i].value = 0;		lzw->table[i].firstchar = 0;		lzw->table[i].length = 0;		lzw->table[i].prev = -1;	}	lzw->codebits = MINBITS;	lzw->code = -1;	lzw->nextcode = LZW_FIRST;	lzw->oldcode = -1;	lzw->resume = 0;	return fz_okay;}voidfz_droplzwd(fz_filter *filter){}static inline void eatbits(fz_lzwd *lzw, int nbits){	lzw->word <<= nbits;	lzw->bidx += nbits;}static inline fz_error * fillbits(fz_lzwd *lzw, fz_buffer *in){	while (lzw->bidx >= 8)	{		if (in->rp + 1 > in->wp)			return fz_ioneedin;		lzw->bidx -= 8;		lzw->word |= *in->rp << lzw->bidx;		in->rp ++;	}	return fz_okay;}static inline void unstuff(fz_lzwd *lzw, fz_buffer *in){	int i = (32 - lzw->bidx) / 8;	while (i-- && in->rp > in->bp)		in->rp --;}fz_error *fz_processlzwd(fz_filter *filter, fz_buffer *in, fz_buffer *out){	fz_lzwd *lzw = (fz_lzwd*)filter;	unsigned char *s;	int len;	if (lzw->resume)	{		lzw->resume = 0;		goto output;	}	while (1)	{		if (fillbits(lzw, in))		{			if (in->eof)			{				if (lzw->bidx > 32 - lzw->codebits)				{					unstuff(lzw, in);					return fz_iodone;				}			}			else			{				return fz_ioneedin;			}		}		lzw->code = lzw->word >> (32 - lzw->codebits);		if (lzw->code == LZW_EOD)		{			eatbits(lzw, lzw->codebits);			unstuff(lzw, in);			return fz_iodone;		}		if (lzw->code == LZW_CLEAR)		{			int oldcodebits = lzw->codebits;			lzw->codebits = MINBITS;			lzw->nextcode = LZW_FIRST;			lzw->code = lzw->word >> (32 - oldcodebits - MINBITS) & ((1 << MINBITS) - 1);			if (lzw->code == LZW_EOD)			{				eatbits(lzw, oldcodebits + MINBITS);				unstuff(lzw, in);				return fz_iodone;			}			eatbits(lzw, oldcodebits + MINBITS);			lzw->oldcode = lzw->code;			if (out->wp + 1 > out->ep)			{				lzw->resume = 1;				return fz_ioneedout;			}			*out->wp++ = lzw->code;			continue;		}		eatbits(lzw, lzw->codebits);		/* if stream starts without a clear code, oldcode is undefined... */		if (lzw->oldcode == -1)		{			lzw->oldcode = lzw->code;			goto output;		}		/* add new entry to the code table */		lzw->table[lzw->nextcode].prev = lzw->oldcode;		lzw->table[lzw->nextcode].firstchar = lzw->table[lzw->oldcode].firstchar;		lzw->table[lzw->nextcode].length = lzw->table[lzw->oldcode].length + 1;		if (lzw->code < lzw->nextcode)			lzw->table[lzw->nextcode].value = lzw->table[lzw->code].firstchar;		else			lzw->table[lzw->nextcode].value = lzw->table[lzw->nextcode].firstchar;		lzw->nextcode ++;		if (lzw->nextcode >= (1 << lzw->codebits) - lzw->earlychange - 1)		{			lzw->codebits ++;			if (lzw->codebits > MAXBITS)				lzw->codebits = MAXBITS;	/* FIXME */		}		lzw->oldcode = lzw->code;output:		/* code maps to a string, copy to output (in reverse...) */		if (lzw->code > 255)		{			if (out->wp + lzw->table[lzw->code].length > out->ep)			{				lzw->resume = 1;				return fz_ioneedout;			}			len = lzw->table[lzw->code].length;			s = out->wp + len;			do			{				*(--s) = lzw->table[lzw->code].value;				lzw->code = lzw->table[lzw->code].prev;			} while (lzw->code >= 0 && s > out->wp);			out->wp += len;		}		/* ... or just a single character */		else		{			if (out->wp + 1 > out->ep)			{				lzw->resume = 1;				return fz_ioneedout;			}			*out->wp++ = lzw->code;		}	}}

⌨️ 快捷键说明

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