コード例 #1
0
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;
		}
	}
コード例 #2
0
ファイル: filt_lzwd.c プロジェクト: MaChao5/pdfviewer-win32
static int
readlzwd(fz_stream *stm, unsigned char *buf, int len)
{
	fz_lzwd *lzw = stm->state;
	unsigned char *p = buf;
	unsigned char *ep = buf + len;
	unsigned char *s;
	int codelen;

	while (lzw->rp < lzw->wp && p < ep)
		*p++ = *lzw->rp++;

	while (p < ep)
	{
		if (lzw->eod)
			return 0;

		if (fillbits(lzw))
		{
			if (lzw->bidx > 32 - lzw->codebits)
			{
				lzw->eod = 1;
				return p - buf;
			}
		}

		lzw->code = lzw->word >> (32 - lzw->codebits);
		lzw->code &= (1 << lzw->codebits) - 1;
		eatbits(lzw, lzw->codebits);

		if (lzw->code == LZW_EOD)
		{
			lzw->eod = 1;
			return p - buf;
		}

		if (lzw->code == LZW_CLEAR)
		{
			lzw->codebits = MINBITS;
			lzw->nextcode = LZW_FIRST;
			lzw->oldcode = -1;
			continue;
		}

		/* 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 if (lzw->code == lzw->nextcode)
			lzw->table[lzw->nextcode].value = lzw->table[lzw->nextcode].firstchar;
		else
			fz_warn("out of range code encountered in lzw decode");

		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)
		{
			codelen = lzw->table[lzw->code].length;
			lzw->rp = lzw->bp;
			lzw->wp = lzw->bp + codelen;

			assert(codelen < MAXLENGTH);

			s = lzw->wp;
			do {
				*(--s) = lzw->table[lzw->code].value;
				lzw->code = lzw->table[lzw->code].prev;
			} while (lzw->code >= 0 && s > lzw->bp);
		}

		/* ... or just a single character */
		else
		{
			lzw->bp[0] = lzw->code;
			lzw->rp = lzw->bp;
			lzw->wp = lzw->bp + 1;
		}

		/* copy to output */
		while (lzw->rp < lzw->wp && p < ep)
			*p++ = *lzw->rp++;
	}

	return p - buf;
}