This is tif_lzw.c in view mode; [Download] [Up]
#ifndef lint static char rcsid[] = "/mode/users/src/master/tiff/libtiff/tif_lzw.c,v 1.1.1.1 1994/04/01 17:15:22 fedor Exp"; #endif /* * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler * Copyright (c) 1991, 1992 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. */ /* * 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 "tiffioP.h" #include <stdio.h> #include <assert.h> #include "prototypes.h" #define MAXCODE(n) ((1 << (n)) - 1) /* * The TIFF spec specifies that encoded bit strings range * from 9 to 12 bits. This is somewhat unfortunate in that * experience indicates full color RGB pictures often need * ~14 bits for reasonable compression. */ #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) #ifdef notdef #define HSIZE 9001 /* 91% occupancy */ #define HSHIFT (8-(16-13)) #else #define HSIZE 5003 /* 80% occupancy */ #define HSHIFT (8-(16-12)) #endif /* * 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 SetMaxCode(sp, v) { \ (sp)->lzw_maxcode = (v)-1; \ if ((sp)->lzw_flags & LZW_COMPAT) \ (sp)->lzw_maxcode++; \ } /* * Decoding-specific state. */ struct decode { short prefixtab[HSIZE]; /* prefix(code) */ u_char suffixtab[CODE_MAX+1]; /* suffix(code) */ u_char stack[HSIZE-(CODE_MAX+1)]; u_char *stackp; /* stack pointer */ int firstchar; /* of string associated w/ last code */ }; /* * Encoding-specific state. */ struct encode { long checkpoint; /* point at which to clear table */ #define CHECK_GAP 10000 /* enc_ratio check interval */ long ratio; /* current compression ratio */ long incount; /* (input) data bytes encoded */ long outcount; /* encoded (output) bytes */ long htab[HSIZE]; /* hash table */ short codetab[HSIZE]; /* code table */ }; #if USE_PROTOTYPES typedef void (*predictorFunc)(char* data, int nbytes, int stride); #else typedef void (*predictorFunc)(); #endif /* * State block for each open TIFF * file using LZW compression/decompression. */ typedef struct { int lzw_oldcode; /* last code encountered */ u_short lzw_flags; #define LZW_RESTART 0x01 /* restart interrupted decode */ #define LZW_COMPAT 0x02 /* read old bit-reversed codes */ u_short lzw_nbits; /* number of bits/code */ u_short lzw_stride; /* horizontal diferencing stride */ u_short lzw_rowsize; /* XXX maybe should be a long? */ predictorFunc lzw_hordiff; int lzw_maxcode; /* maximum code for lzw_nbits */ long lzw_bitoff; /* bit offset into data */ long lzw_bitsize; /* size of strip in bits */ int lzw_free_ent; /* next free entry in hash table */ union { struct decode dec; struct encode enc; } u; } LZWState; #define dec_prefix u.dec.prefixtab #define dec_suffix u.dec.suffixtab #define dec_stack u.dec.stack #define dec_stackp u.dec.stackp #define dec_firstchar u.dec.firstchar #define enc_checkpoint u.enc.checkpoint #define enc_ratio u.enc.ratio #define enc_incount u.enc.incount #define enc_outcount u.enc.outcount #define enc_htab u.enc.htab #define enc_codetab u.enc.codetab /* masks for extracting/inserting variable length bit codes */ static const u_char rmask[9] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; static const u_char lmask[9] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; #if USE_PROTOTYPES static int LZWPreEncode(TIFF*); static int LZWEncode(TIFF*, u_char*, int, u_int); static int LZWEncodePredRow(TIFF*, u_char*, int, u_int); static int LZWEncodePredTile(TIFF*, u_char*, int, u_int); static int LZWPostEncode(TIFF*); static int LZWDecode(TIFF*, u_char*, int, u_int); static int LZWDecodePredRow(TIFF*, u_char*, int, u_int); static int LZWDecodePredTile(TIFF*, u_char*, int, u_int); static int LZWPreDecode(TIFF*); static int LZWCleanup(TIFF*); static int GetNextCode(TIFF*); static void PutNextCode(TIFF*, int); static void cl_block(TIFF*); static void cl_hash(LZWState*); extern int TIFFFlushData1(TIFF *); #else static int LZWPreEncode(), LZWEncode(), LZWPostEncode(); static int LZWEncodePredRow(), LZWEncodePredTile(); static int LZWPreDecode(), LZWDecode(); static int LZWDecodePredRow(), LZWDecodePredTile(); static int LZWCleanup(); static int GetNextCode(); static void PutNextCode(); static void cl_block(); static void cl_hash(); extern int TIFFFlushData1(); #endif TIFFInitLZW(tif) TIFF *tif; { tif->tif_predecode = LZWPreDecode; tif->tif_decoderow = LZWDecode; tif->tif_decodestrip = LZWDecode; tif->tif_decodetile = LZWDecode; tif->tif_preencode = LZWPreEncode; tif->tif_postencode = LZWPostEncode; tif->tif_encoderow = LZWEncode; tif->tif_encodestrip = LZWEncode; tif->tif_encodetile = LZWEncode; tif->tif_cleanup = LZWCleanup; return (1); } static DECLARE4(LZWCheckPredictor, TIFF*, tif, LZWState*, sp, predictorFunc, pred8bit, predictorFunc, pred16bit ) { TIFFDirectory *td = &tif->tif_dir; switch (td->td_predictor) { case 1: break; case 2: sp->lzw_stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); switch (td->td_bitspersample) { case 8: sp->lzw_hordiff = pred8bit; break; case 16: sp->lzw_hordiff = pred16bit; break; default: TIFFError(tif->tif_name, "Horizontal differencing \"Predictor\" not supported with %d-bit samples", td->td_bitspersample); return (0); } break; default: TIFFError(tif->tif_name, "\"Predictor\" value %d not supported", td->td_predictor); return (0); } if (sp->lzw_hordiff) { /* * Calculate the scanline/tile-width size in bytes. */ if (isTiled(tif)) sp->lzw_rowsize = TIFFTileRowSize(tif); else sp->lzw_rowsize = TIFFScanlineSize(tif); } return (1); } /* * LZW Decoder. */ #define REPEAT4(n, op) \ switch (n) { \ default: { int i; for (i = n-4; i > 0; i--) { op; } } \ case 4: op; \ case 3: op; \ case 2: op; \ case 1: op; \ case 0: ; \ } static void DECLARE3(horizontalAccumulate8, register char*, cp, register int, cc, register int, stride ) { if (cc > stride) { cc -= stride; do { REPEAT4(stride, cp[stride] += cp[0]; cp++) cc -= stride; } while (cc > 0); } } static void DECLARE3(horizontalAccumulate16, char*, cp, int, cc, register int, stride ) { register short* wp = (short *)cp; register int wc = cc / 2; if (wc > stride) { wc -= stride; do { REPEAT4(stride, wp[stride] += wp[0]; wp++) wc -= stride; } while (wc > 0); } } /* * Setup state for decoding a strip. */ static LZWPreDecode(tif) TIFF *tif; { register LZWState *sp = (LZWState *)tif->tif_data; register int code; if (sp == NULL) { tif->tif_data = malloc(sizeof (LZWState)); if (tif->tif_data == NULL) { TIFFError("LZWPreDecode", "No space for LZW state block"); return (0); } sp = (LZWState *)tif->tif_data; sp->lzw_flags = 0; sp->lzw_hordiff = 0; sp->lzw_rowsize = 0; if (!LZWCheckPredictor(tif, sp, horizontalAccumulate8, horizontalAccumulate16)) return (0); if (sp->lzw_hordiff) { /* * Override default decoding method with * one that does the predictor stuff. */ tif->tif_decoderow = LZWDecodePredRow; tif->tif_decodestrip = LZWDecodePredTile; tif->tif_decodetile = LZWDecodePredTile; } } else sp->lzw_flags &= ~LZW_RESTART; sp->lzw_nbits = BITS_MIN; /* * Pre-load the table. */ for (code = 255; code >= 0; code--) sp->dec_suffix[code] = (u_char)code; sp->lzw_free_ent = CODE_FIRST; sp->lzw_bitoff = 0; /* calculate data size in bits */ sp->lzw_bitsize = tif->tif_rawdatasize; sp->lzw_bitsize = (sp->lzw_bitsize << 3) - (BITS_MAX-1); sp->dec_stackp = sp->dec_stack; sp->lzw_oldcode = -1; sp->dec_firstchar = -1; /* * Check for old bit-reversed codes. All the flag * manipulations are to insure only one warning is * given for a file. */ if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) { if ((sp->lzw_flags & LZW_COMPAT) == 0) TIFFWarning(tif->tif_name, "Old-style LZW codes, convert file"); sp->lzw_flags |= LZW_COMPAT; } else sp->lzw_flags &= ~LZW_COMPAT; SetMaxCode(sp, MAXCODE(BITS_MIN)); return (1); } /* * Decode a "hunk of data". */ static LZWDecode(tif, op0, occ0, s) TIFF *tif; u_char *op0; u_int s; { register char *op = (char *)op0; register int occ = occ0; register LZWState *sp = (LZWState *)tif->tif_data; register int code; register u_char *stackp; int firstchar, oldcode, incode; stackp = sp->dec_stackp; /* * Restart interrupted unstacking operations. */ if (sp->lzw_flags & LZW_RESTART) { do { if (--occ < 0) { /* end of scanline */ sp->dec_stackp = stackp; return (1); } *op++ = *--stackp; } while (stackp > sp->dec_stack); sp->lzw_flags &= ~LZW_RESTART; } oldcode = sp->lzw_oldcode; firstchar = sp->dec_firstchar; while (occ > 0 && (code = GetNextCode(tif)) != CODE_EOI) { if (code == CODE_CLEAR) { bzero(sp->dec_prefix, sizeof (sp->dec_prefix)); sp->lzw_free_ent = CODE_FIRST; sp->lzw_nbits = BITS_MIN; SetMaxCode(sp, MAXCODE(BITS_MIN)); if ((code = GetNextCode(tif)) == CODE_EOI) break; *op++ = code, occ--; oldcode = firstchar = code; continue; } incode = code; /* * When a code is not in the table we use (as spec'd): * StringFromCode(oldcode) + * FirstChar(StringFromCode(oldcode)) */ if (code >= sp->lzw_free_ent) { /* code not in table */ *stackp++ = firstchar; code = oldcode; } /* * Generate output string (first in reverse). */ for (; code >= 256; code = sp->dec_prefix[code]) *stackp++ = sp->dec_suffix[code]; *stackp++ = firstchar = sp->dec_suffix[code]; do { if (--occ < 0) { /* end of scanline */ sp->lzw_flags |= LZW_RESTART; break; } *op++ = *--stackp; } while (stackp > sp->dec_stack); /* * Add the new entry to the code table. */ if ((code = sp->lzw_free_ent) < CODE_MAX) { sp->dec_prefix[code] = (u_short)oldcode; sp->dec_suffix[code] = firstchar; sp->lzw_free_ent++; /* * If the next entry is too big for the * current code size, then increase the * size up to the maximum possible. */ if (sp->lzw_free_ent > sp->lzw_maxcode) { sp->lzw_nbits++; if (sp->lzw_nbits > BITS_MAX) sp->lzw_nbits = BITS_MAX; SetMaxCode(sp, MAXCODE(sp->lzw_nbits)); } } oldcode = incode; } sp->dec_stackp = stackp; sp->lzw_oldcode = oldcode; sp->dec_firstchar = firstchar; 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); } /* * Decode a scanline and apply the predictor routine. */ static LZWDecodePredRow(tif, op0, occ0, s) TIFF *tif; u_char *op0; u_int s; { LZWState *sp = (LZWState *)tif->tif_data; if (LZWDecode(tif, op0, occ0, s)) { (*sp->lzw_hordiff)((char *)op0, occ0, sp->lzw_stride); return (1); } else return (0); } /* * Decode a tile/strip and apply the predictor routine. * Note that horizontal differencing must be done on a * row-by-row basis. The width of a "row" has already * been calculated at pre-decode time according to the * strip/tile dimensions. */ static LZWDecodePredTile(tif, op0, occ0, s) TIFF *tif; u_char *op0; u_int s; { LZWState *sp = (LZWState *)tif->tif_data; if (!LZWDecode(tif, op0, occ0, s)) return (0); while (occ0 > 0) { (*sp->lzw_hordiff)((char *)op0, sp->lzw_rowsize, sp->lzw_stride); occ0 -= sp->lzw_rowsize; op0 += sp->lzw_rowsize; } return (1); } /* * Get the next code from the raw data buffer. */ static GetNextCode(tif) TIFF *tif; { register LZWState *sp = (LZWState *)tif->tif_data; register int code, bits; register long r_off; register u_char *bp; /* * This check shouldn't be necessary because each * strip is suppose to be terminated with CODE_EOI. * At worst it's a substitute for the CODE_EOI that's * supposed to be there (see calculation of lzw_bitsize * in LZWPreDecode()). */ if (sp->lzw_bitoff > sp->lzw_bitsize) { TIFFWarning(tif->tif_name, "LZWDecode: Strip %d not terminated with EOI code", tif->tif_curstrip); return (CODE_EOI); } r_off = sp->lzw_bitoff; bits = sp->lzw_nbits; /* * Get to the first byte. */ bp = (u_char *)tif->tif_rawdata + (r_off >> 3); r_off &= 7; if (sp->lzw_flags & LZW_COMPAT) { /* Get first part (low order bits) */ code = (*bp++ >> r_off); r_off = 8 - r_off; /* now, offset into code word */ bits -= r_off; /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if (bits >= 8) { code |= *bp++ << r_off; r_off += 8; bits -= 8; } /* high order bits. */ code |= (*bp & rmask[bits]) << r_off; } else { r_off = 8 - r_off; /* convert offset to count */ code = *bp++ & rmask[r_off]; /* high order bits */ bits -= r_off; if (bits >= 8) { code = (code<<8) | *bp++; bits -= 8; } /* low order bits */ code = (code << bits) | (((unsigned)(*bp & lmask[bits])) >> (8 - bits)); } sp->lzw_bitoff += sp->lzw_nbits; return (code); } /* * LZW Encoding. */ static void DECLARE3(horizontalDifference8, register char*, cp, register int, cc, register int, stride ) { if (cc > stride) { cc -= stride; cp += cc - 1; do { REPEAT4(stride, cp[stride] -= cp[0]; cp--) cc -= stride; } while (cc > 0); } } static void DECLARE3(horizontalDifference16, char*, cp, int, cc, register int, stride ) { register short *wp = (short *)cp; register int wc = cc/2; if (wc > stride) { wc -= stride; wp += wc - 1; do { REPEAT4(stride, wp[stride] -= wp[0]; wp--) wc -= stride; } while (wc > 0); } } /* * Reset encoding state at the start of a strip. */ static LZWPreEncode(tif) TIFF *tif; { register LZWState *sp = (LZWState *)tif->tif_data; if (sp == NULL) { tif->tif_data = malloc(sizeof (LZWState)); if (tif->tif_data == NULL) { TIFFError("LZWPreEncode", "No space for LZW state block"); return (0); } sp = (LZWState *)tif->tif_data; sp->lzw_flags = 0; sp->lzw_hordiff = 0; if (!LZWCheckPredictor(tif, sp, horizontalDifference8, horizontalDifference16)) return (0); if (sp->lzw_hordiff) { tif->tif_encoderow = LZWEncodePredRow; tif->tif_encodestrip = LZWEncodePredTile; tif->tif_encodetile = LZWEncodePredTile; } } sp->enc_checkpoint = CHECK_GAP; SetMaxCode(sp, MAXCODE(sp->lzw_nbits = BITS_MIN)+1); cl_hash(sp); /* clear hash table */ sp->lzw_bitoff = 0; sp->lzw_bitsize = (tif->tif_rawdatasize << 3) - (BITS_MAX-1); sp->lzw_oldcode = -1; /* generates CODE_CLEAR in LZWEncode */ return (1); } /* * Encode a scanline of pixels. * * Uses an open addressing double hashing (no chaining) on the * prefix code/next character combination. We do a variant of * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's * relatively-prime secondary probe. Here, the modular division * first probe is gives way to a faster exclusive-or manipulation. * Also do block compression with an adaptive reset, whereby the * code table is cleared when the compression ratio decreases, * but after the table fills. The variable-length output codes * are re-sized at this point, and a CODE_CLEAR is generated * for the decoder. */ static LZWEncode(tif, bp, cc, s) TIFF *tif; u_char *bp; int cc; u_int s; { static char module[] = "LZWEncode"; register LZWState *sp; register long fcode; register int h, c, ent, disp; if ((sp = (LZWState *)tif->tif_data) == NULL) return (0); ent = sp->lzw_oldcode; if (ent == -1 && cc > 0) { PutNextCode(tif, CODE_CLEAR); ent = *bp++; cc--; sp->enc_incount++; } while (cc > 0) { c = *bp++; cc--; sp->enc_incount++; fcode = ((long)c << BITS_MAX) + ent; h = (c << HSHIFT) ^ ent; /* xor hashing */ if (sp->enc_htab[h] == fcode) { ent = sp->enc_codetab[h]; continue; } if (sp->enc_htab[h] >= 0) { /* * Primary hash failed, check secondary hash. */ disp = HSIZE - h; if (h == 0) disp = 1; do { if ((h -= disp) < 0) h += HSIZE; if (sp->enc_htab[h] == fcode) { ent = sp->enc_codetab[h]; goto hit; } } while (sp->enc_htab[h] >= 0); } /* * New entry, emit code and add to table. */ PutNextCode(tif, ent); ent = c; sp->enc_codetab[h] = sp->lzw_free_ent++; sp->enc_htab[h] = fcode; if (sp->lzw_free_ent == CODE_MAX-1) { /* table is full, emit clear code and reset */ cl_hash(sp); PutNextCode(tif, CODE_CLEAR); SetMaxCode(sp, MAXCODE(sp->lzw_nbits = BITS_MIN)+1); } else { /* * If the next entry is going to be too big for * the code size, then increase it, if possible. */ if (sp->lzw_free_ent > sp->lzw_maxcode) { sp->lzw_nbits++; assert(sp->lzw_nbits <= BITS_MAX); SetMaxCode(sp, MAXCODE(sp->lzw_nbits)+1); } else if (sp->enc_incount >= sp->enc_checkpoint) cl_block(tif); } hit: ; } sp->lzw_oldcode = ent; return (1); } static LZWEncodePredRow(tif, bp, cc, s) TIFF *tif; u_char *bp; int cc; u_int s; { LZWState *sp = (LZWState *)tif->tif_data; /* XXX horizontal differencing alters user's data XXX */ (*sp->lzw_hordiff)((char *)bp, cc, sp->lzw_stride); return (LZWEncode(tif, bp, cc, s)); } static LZWEncodePredTile(tif, bp0, cc0, s) TIFF *tif; u_char *bp0; int cc0; u_int s; { LZWState *sp = (LZWState *)tif->tif_data; int cc = cc0; u_char *bp = bp0; while (cc > 0) { (*sp->lzw_hordiff)((char *)bp, sp->lzw_rowsize, sp->lzw_stride); cc -= sp->lzw_rowsize; bp += sp->lzw_rowsize; } return (LZWEncode(tif, bp0, cc0, s)); } /* * Finish off an encoded strip by flushing the last * string and tacking on an End Of Information code. */ static LZWPostEncode(tif) TIFF *tif; { LZWState *sp = (LZWState *)tif->tif_data; if (sp->lzw_oldcode != -1) { PutNextCode(tif, sp->lzw_oldcode); sp->lzw_oldcode = -1; } PutNextCode(tif, CODE_EOI); return (1); } static void PutNextCode(tif, c) TIFF *tif; int c; { register LZWState *sp = (LZWState *)tif->tif_data; register long r_off; register int bits, code = c; register char *bp; r_off = sp->lzw_bitoff; bits = sp->lzw_nbits; /* * Flush buffer if code doesn't fit. */ if (r_off + bits > sp->lzw_bitsize) { /* * Calculate the number of full bytes that can be * written and save anything else for the next write. */ if (r_off & 7) { tif->tif_rawcc = r_off >> 3; bp = tif->tif_rawdata + tif->tif_rawcc; (void) TIFFFlushData1(tif); tif->tif_rawdata[0] = *bp; } else { /* * Otherwise, on a byte boundary (in * which tiff_rawcc is already correct). */ (void) TIFFFlushData1(tif); } bp = tif->tif_rawdata; sp->lzw_bitoff = (r_off &= 7); } else { /* * Get to the first byte. */ bp = tif->tif_rawdata + (r_off >> 3); r_off &= 7; } /* * Note that lzw_bitoff is maintained as the bit offset * into the buffer w/ a right-to-left orientation (i.e. * lsb-to-msb). The bits, however, go in the file in * an msb-to-lsb order. */ bits -= (8 - r_off); *bp = (*bp & lmask[r_off]) | (code >> bits); bp++; if (bits >= 8) { bits -= 8; *bp++ = code >> bits; } if (bits) *bp = (code & rmask[bits]) << (8 - bits); /* * enc_outcount is used by the compression analysis machinery * which resets the compression tables when the compression * ratio goes up. lzw_bitoff is used here (in PutNextCode) for * inserting codes into the output buffer. tif_rawcc must * be updated for the mainline write code in TIFFWriteScanline() * so that data is flushed when the end of a strip is reached. * Note that the latter is rounded up to ensure that a non-zero * byte count is present. */ sp->enc_outcount += sp->lzw_nbits; sp->lzw_bitoff += sp->lzw_nbits; tif->tif_rawcc = (sp->lzw_bitoff + 7) >> 3; } /* * Check compression ratio and, if things seem to * be slipping, clear the hash table and reset state. */ static void cl_block(tif) TIFF *tif; { register LZWState *sp = (LZWState *)tif->tif_data; register long rat; sp->enc_checkpoint = sp->enc_incount + CHECK_GAP; if (sp->enc_incount > 0x007fffff) { /* shift will overflow */ rat = sp->enc_outcount >> 8; rat = (rat == 0 ? 0x7fffffff : sp->enc_incount / rat); } else rat = (sp->enc_incount<<8)/sp->enc_outcount; /* 8 fract bits */ if (rat <= sp->enc_ratio) { cl_hash(sp); PutNextCode(tif, CODE_CLEAR); SetMaxCode(sp, MAXCODE(sp->lzw_nbits = BITS_MIN)+1); } else sp->enc_ratio = rat; } /* * Reset code table and related statistics. */ static void cl_hash(sp) LZWState *sp; { register long *htab_p = sp->enc_htab+HSIZE; register long i, m1 = -1; i = HSIZE - 16; do { *(htab_p-16) = m1; *(htab_p-15) = m1; *(htab_p-14) = m1; *(htab_p-13) = m1; *(htab_p-12) = m1; *(htab_p-11) = m1; *(htab_p-10) = m1; *(htab_p-9) = m1; *(htab_p-8) = m1; *(htab_p-7) = m1; *(htab_p-6) = m1; *(htab_p-5) = m1; *(htab_p-4) = m1; *(htab_p-3) = m1; *(htab_p-2) = m1; *(htab_p-1) = m1; htab_p -= 16; } while ((i -= 16) >= 0); for (i += 16; i > 0; i--) *--htab_p = m1; sp->enc_ratio = 0; sp->enc_incount = 0; sp->enc_outcount = 0; sp->lzw_free_ent = CODE_FIRST; } static LZWCleanup(tif) TIFF *tif; { if (tif->tif_data) { free(tif->tif_data); tif->tif_data = NULL; } } /* * Copyright (c) 1985, 1986 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * James A. Woods, derived from original work by Spencer Thomas * and Joseph Orost. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.