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

📄 tif_lzw.c

📁 一个国人自己实现图像库的程序(有参考价值)
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /cvsroot/libtiff-lzw-compression-kit/tif_lzw.c,v 1.2 2001/09/25 02:14:31 warmerda Exp $ *//* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. */#include "tiffiop.h"#ifdef LZW_SUPPORT/* * TIFF Library. * Rev 5.0 Lempel-Ziv & Welch Compression Support * * This code is derived from the compress program whose code is * derived from software contributed to Berkeley by James A. Woods, * derived from original work by Spencer Thomas and Joseph Orost. * * The original Berkeley copyright notice appears below in its entirety. */#include "tif_predict.h"#include <assert.h>#include <stdio.h>/* * NB: The 5.0 spec describes a different algorithm than Aldus *     implements.  Specifically, Aldus does code length transitions *     one code earlier than should be done (for real LZW). *     Earlier versions of this library implemented the correct *     LZW algorithm, but emitted codes in a bit order opposite *     to the TIFF spec.  Thus, to maintain compatibility w/ Aldus *     we interpret MSB-LSB ordered codes to be images written w/ *     old versions of this library, but otherwise adhere to the *     Aldus "off by one" algorithm. * * Future revisions to the TIFF spec are expected to "clarify this issue". */#define	LZW_COMPAT		/* include backwards compatibility code *//* * Each strip of data is supposed to be terminated by a CODE_EOI. * If the following #define is included, the decoder will also * check for end-of-strip w/o seeing this code.  This makes the * library more robust, but also slower. */#define	LZW_CHECKEOS		/* include checks for strips w/o EOI code */#define MAXCODE(n)	((1L<<(n))-1)/* * The TIFF spec specifies that encoded bit * strings range from 9 to 12 bits. */#define	BITS_MIN	9		/* start with 9 bits */#define	BITS_MAX	12		/* max of 12 bit strings *//* predefined codes */#define	CODE_CLEAR	256		/* code to clear string table */#define	CODE_EOI	257		/* end-of-information code */#define CODE_FIRST	258		/* first free code entry */#define	CODE_MAX	MAXCODE(BITS_MAX)#define	HSIZE		9001L		/* 91% occupancy */#define	HSHIFT		(13-8)#ifdef LZW_COMPAT/* NB: +1024 is for compatibility with old files */#define	CSIZE		(MAXCODE(BITS_MAX)+1024L)#else#define	CSIZE		(MAXCODE(BITS_MAX)+1L)#endif/* * State block for each open TIFF file using LZW * compression/decompression.  Note that the predictor * state block must be first in this data structure. */typedef	struct {	TIFFPredictorState predict;	/* predictor super class */	u_short		nbits;		/* # of bits/code */	u_short		maxcode;	/* maximum code for lzw_nbits */	u_short		free_ent;	/* next free entry in hash table */	long		nextdata;	/* next bits of i/o */	long		nextbits;	/* # of valid bits in lzw_nextdata */        int             rw_mode;        /* preserve rw_mode from init */} LZWBaseState;#define	lzw_nbits	base.nbits#define	lzw_maxcode	base.maxcode#define	lzw_free_ent	base.free_ent#define	lzw_nextdata	base.nextdata#define	lzw_nextbits	base.nextbits/* * Decoding-specific state. */typedef struct code_ent {	struct code_ent *next;	u_short	length;			/* string len, including this token */	u_char	value;			/* data value */	u_char	firstchar;		/* first token of string */} code_t;typedef	int (*decodeFunc)(TIFF*, tidata_t, tsize_t, tsample_t);typedef struct {	LZWBaseState base;	long	dec_nbitsmask;		/* lzw_nbits 1 bits, right adjusted */	long	dec_restart;		/* restart count */#ifdef LZW_CHECKEOS	long	dec_bitsleft;		/* available bits in raw data */#endif	decodeFunc dec_decode;		/* regular or backwards compatible */	code_t*	dec_codep;		/* current recognized code */	code_t*	dec_oldcodep;		/* previously recognized code */	code_t*	dec_free_entp;		/* next free entry */	code_t*	dec_maxcodep;		/* max available entry */	code_t*	dec_codetab;		/* kept separate for small machines */} LZWDecodeState;/* * Encoding-specific state. */typedef uint16 hcode_t;			/* codes fit in 16 bits */typedef struct {	long	hash;	hcode_t	code;} hash_t;typedef struct {	LZWBaseState base;	int	enc_oldcode;		/* last code encountered */	long	enc_checkpoint;		/* point at which to clear table */#define CHECK_GAP	10000		/* enc_ratio check interval */	long	enc_ratio;		/* current compression ratio */	long	enc_incount;		/* (input) data bytes encoded */	long	enc_outcount;		/* encoded (output) bytes */	tidata_t enc_rawlimit;		/* bound on tif_rawdata buffer */	hash_t*	enc_hashtab;		/* kept separate for small machines */} LZWEncodeState;#define	LZWState(tif)		((LZWBaseState*) (tif)->tif_data)#define	DecoderState(tif)	((LZWDecodeState*) LZWState(tif))#define	EncoderState(tif)	((LZWEncodeState*) LZWState(tif))static	int LZWDecode(TIFF*, tidata_t, tsize_t, tsample_t);#ifdef LZW_COMPATstatic	int LZWDecodeCompat(TIFF*, tidata_t, tsize_t, tsample_t);#endifstatic	void cl_hash(LZWEncodeState*);/* * LZW Decoder. */#ifdef LZW_CHECKEOS/* * This check shouldn't be necessary because each * strip is suppose to be terminated with CODE_EOI. */#define	NextCode(_tif, _sp, _bp, _code, _get) {				\	if ((_sp)->dec_bitsleft < nbits) {				\		TIFFWarning(_tif->tif_name,				\		    "LZWDecode: Strip %d not terminated with EOI code", \		    _tif->tif_curstrip);				\		_code = CODE_EOI;					\	} else {							\		_get(_sp,_bp,_code);					\		(_sp)->dec_bitsleft -= nbits;				\	}								\}#else#define	NextCode(tif, sp, bp, code, get) get(sp, bp, code)#endifstatic intLZWSetupDecode(TIFF* tif){	LZWDecodeState* sp = DecoderState(tif);	static const char module[] = " LZWSetupDecode";	int code;	assert(sp != NULL);	if (sp->dec_codetab == NULL) {		sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));		if (sp->dec_codetab == NULL) {			TIFFError(module, "No space for LZW code table");			return (0);		}		/*		 * Pre-load the table.		 */                code = 255;                do {                    sp->dec_codetab[code].value = code;                    sp->dec_codetab[code].firstchar = code;                    sp->dec_codetab[code].length = 1;                    sp->dec_codetab[code].next = NULL;                } while (code--);	}	return (1);}/* * Setup state for decoding a strip. */static intLZWPreDecode(TIFF* tif, tsample_t s){	LZWDecodeState *sp = DecoderState(tif);	(void) s;	assert(sp != NULL);	/*	 * Check for old bit-reversed codes.	 */	if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {#ifdef LZW_COMPAT		if (!sp->dec_decode) {			TIFFWarning(tif->tif_name,			    "Old-style LZW codes, convert file");			/*			 * Override default decoding methods with			 * ones that deal with the old coding.			 * Otherwise the predictor versions set			 * above will call the compatibility routines			 * through the dec_decode method.			 */			tif->tif_decoderow = LZWDecodeCompat;			tif->tif_decodestrip = LZWDecodeCompat;			tif->tif_decodetile = LZWDecodeCompat;			/*			 * If doing horizontal differencing, must			 * re-setup the predictor logic since we			 * switched the basic decoder methods...			 */			(*tif->tif_setupdecode)(tif);			sp->dec_decode = LZWDecodeCompat;		}		sp->lzw_maxcode = MAXCODE(BITS_MIN);#else /* !LZW_COMPAT */		if (!sp->dec_decode) {			TIFFError(tif->tif_name,			    "Old-style LZW codes not supported");			sp->dec_decode = LZWDecode;		}		return (0);#endif/* !LZW_COMPAT */	} else {		sp->lzw_maxcode = MAXCODE(BITS_MIN)-1;		sp->dec_decode = LZWDecode;	}	sp->lzw_nbits = BITS_MIN;	sp->lzw_nextbits = 0;	sp->lzw_nextdata = 0;	sp->dec_restart = 0;	sp->dec_nbitsmask = MAXCODE(BITS_MIN);#ifdef LZW_CHECKEOS	sp->dec_bitsleft = tif->tif_rawcc << 3;#endif	sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;	/*	 * Zero entries that are not yet filled in.  We do	 * this to guard against bogus input data that causes	 * us to index into undefined entries.  If you can	 * come up with a way to safely bounds-check input codes	 * while decoding then you can remove this operation.	 */	_TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));	sp->dec_oldcodep = &sp->dec_codetab[-1];	sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];	return (1);}/* * Decode a "hunk of data". */#define	GetNextCode(sp, bp, code) {				\	nextdata = (nextdata<<8) | *(bp)++;			\	nextbits += 8;						\	if (nextbits < nbits) {					\		nextdata = (nextdata<<8) | *(bp)++;		\		nextbits += 8;					\	}							\	code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask);	\	nextbits -= nbits;					\}static voidcodeLoop(TIFF* tif){	TIFFError(tif->tif_name,	    "LZWDecode: Bogus encoding, loop in the code table; scanline %d",	    tif->tif_row);}static intLZWDecode(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s){	LZWDecodeState *sp = DecoderState(tif);	char *op = (char*) op0;	long occ = (long) occ0;	char *tp;	u_char *bp;	hcode_t code;	int len;	long nbits, nextbits, nextdata, nbitsmask;	code_t *codep, *free_entp, *maxcodep, *oldcodep;	(void) s;	assert(sp != NULL);	/*	 * Restart interrupted output operation.	 */	if (sp->dec_restart) {		long residue;		codep = sp->dec_codep;		residue = codep->length - sp->dec_restart;		if (residue > occ) {			/*			 * Residue from previous decode is sufficient			 * to satisfy decode request.  Skip to the			 * start of the decoded string, place decoded			 * values in the output buffer, and return.			 */			sp->dec_restart += occ;			do {				codep = codep->next;			} while (--residue > occ && codep);			if (codep) {				tp = op + occ;				do {					*--tp = codep->value;					codep = codep->next;				} while (--occ && codep);			}			return (1);		}		/*		 * Residue satisfies only part of the decode request.		 */		op += residue, occ -= residue;		tp = op;		do {			int t;			--tp;			t = codep->value;			codep = codep->next;			*tp = t;		} while (--residue && codep);		sp->dec_restart = 0;	}	bp = (u_char *)tif->tif_rawcp;	nbits = sp->lzw_nbits;	nextdata = sp->lzw_nextdata;	nextbits = sp->lzw_nextbits;	nbitsmask = sp->dec_nbitsmask;	oldcodep = sp->dec_oldcodep;	free_entp = sp->dec_free_entp;	maxcodep = sp->dec_maxcodep;	while (occ > 0) {		NextCode(tif, sp, bp, code, GetNextCode);		if (code == CODE_EOI)			break;		if (code == CODE_CLEAR) {			free_entp = sp->dec_codetab + CODE_FIRST;			nbits = BITS_MIN;			nbitsmask = MAXCODE(BITS_MIN);			maxcodep = sp->dec_codetab + nbitsmask-1;			NextCode(tif, sp, bp, code, GetNextCode);			if (code == CODE_EOI)				break;			*op++ = (char)code, occ--;			oldcodep = sp->dec_codetab + code;			continue;		}		codep = sp->dec_codetab + code;		/*	 	 * Add the new entry to the code table.	 	 */		assert(&sp->dec_codetab[0] <= free_entp && free_entp < &sp->dec_codetab[CSIZE]);		free_entp->next = oldcodep;		free_entp->firstchar = free_entp->next->firstchar;		free_entp->length = free_entp->next->length+1;		free_entp->value = (codep < free_entp) ?		    codep->firstchar : free_entp->firstchar;		if (++free_entp > maxcodep) {			if (++nbits > BITS_MAX)		/* should not happen */				nbits = BITS_MAX;			nbitsmask = MAXCODE(nbits);			maxcodep = sp->dec_codetab + nbitsmask-1;		}		oldcodep = codep;		if (code >= 256) {			/*		 	 * Code maps to a string, copy string			 * value to output (written in reverse).		 	 */			if (codep->length > occ) {				/*				 * String is too long for decode buffer,				 * locate portion that will fit, copy to				 * the decode buffer, and setup restart				 * logic for the next decoding call.				 */				sp->dec_codep = codep;				do {					codep = codep->next;				} while (codep && codep->length > occ);				if (codep) {					sp->dec_restart = occ;					tp = op + occ;					do  {						*--tp = codep->value;						codep = codep->next;					}  while (--occ && codep);					if (codep)						codeLoop(tif);				}				break;			}			len = codep->length;			tp = op + len;			do {				int t;				--tp;				t = codep->value;				codep = codep->next;				*tp = t;			} while (codep && tp > op);			if (codep) {			    codeLoop(tif);			    break;			}			op += len, occ -= len;		} else			*op++ = (char)code, occ--;	}	tif->tif_rawcp = (tidata_t) bp;	sp->lzw_nbits = (u_short) nbits;	sp->lzw_nextdata = nextdata;	sp->lzw_nextbits = nextbits;	sp->dec_nbitsmask = nbitsmask;	sp->dec_oldcodep = oldcodep;	sp->dec_free_entp = free_entp;	sp->dec_maxcodep = maxcodep;	if (occ > 0) {		TIFFError(tif->tif_name,		"LZWDecode: Not enough data at scanline %d (short %d bytes)",		    tif->tif_row, occ);		return (0);	}	return (1);}#ifdef LZW_COMPAT/* * Decode a "hunk of data" for old images. */#define	GetNextCodeCompat(sp, bp, code) {			\	nextdata |= (u_long) *(bp)++ << nextbits;		\	nextbits += 8;						\	if (nextbits < nbits) {					\		nextdata |= (u_long) *(bp)++ << nextbits;	\		nextbits += 8;					\	}							\	code = (hcode_t)(nextdata & nbitsmask);			\	nextdata >>= nbits;					\	nextbits -= nbits;					\}static intLZWDecodeCompat(TIFF* tif, tidata_t op0, tsize_t occ0, tsample_t s){	LZWDecodeState *sp = DecoderState(tif);	char *op = (char*) op0;	long occ = (long) occ0;	char *tp;	u_char *bp;	int code, nbits;	long nextbits, nextdata, nbitsmask;	code_t *codep, *free_entp, *maxcodep, *oldcodep;	(void) s;	assert(sp != NULL);	/*	 * Restart interrupted output operation.

⌨️ 快捷键说明

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