This is tif_lzw.c in view mode; [Download] [Up]
#ifndef lint static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_lzw.c,v 1.46 93/01/28 16:59:24 sam 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 <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) ((1<<(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 9001 /* 91% occupancy */ #define HSHIFT (13-8) #ifdef LZW_COMPAT /* NB: +1024 is for compatibility with old files */ #define CSIZE (MAXCODE(BITS_MAX)+1024) #else #define CSIZE (MAXCODE(BITS_MAX)+1) #endif #if USE_PROTOTYPES typedef void (*predictorFunc)(char* data, u_long nbytes, int stride); #else typedef void (*predictorFunc)(); #endif /* * State block for each open TIFF * file using LZW compression/decompression. */ typedef struct { predictorFunc hordiff; /* horizontal differencing method */ u_long rowsize; /* width of tile/strip/row */ u_short stride; /* horizontal diferencing stride */ 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 */ } LZWState; #define lzw_hordiff base.hordiff #define lzw_rowsize base.rowsize #define lzw_stride base.stride #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; #if USE_PROTOTYPES typedef int (*decodeFunc)(TIFF*, u_char*, u_long, u_int); #else typedef int (*decodeFunc)(); #endif typedef struct { LZWState 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[CSIZE]; } LZWDecodeState; /* * Encoding-specific state. */ typedef struct { long hash; long code; } hash_t; typedef struct { LZWState 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 */ char *enc_rawlimit; /* bound on tif_rawdata buffer */ hash_t enc_hashtab[HSIZE]; } LZWEncodeState; #if USE_PROTOTYPES static int LZWEncodePredRow(TIFF*, u_char*, u_long, u_int); static int LZWEncodePredTile(TIFF*, u_char*, u_long, u_int); static int LZWDecode(TIFF*, u_char*, u_long, u_int); #ifdef LZW_COMPAT static int LZWDecodeCompat(TIFF*, u_char*, u_long, u_int); #endif static int LZWDecodePredRow(TIFF*, u_char*, u_long, u_int); static int LZWDecodePredTile(TIFF*, u_char*, u_long, u_int); static void cl_hash(LZWEncodeState*); #else static int LZWDecode(); static int LZWEncodePredRow(); static int LZWEncodePredTile(); static int LZWDecode(); #ifdef LZW_COMPAT static int LZWDecodeCompat(); #endif static int LZWDecodePredRow(); static int LZWDecodePredTile(); static void cl_hash(); #endif static DECLARE4(LZWCheckPredictor, TIFF*, tif, LZWState*, sp, predictorFunc, pred8bit, predictorFunc, pred16bit ) { TIFFDirectory *td = &tif->tif_dir; sp->hordiff = NULL; switch (td->td_predictor) { case 1: break; case 2: sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ? td->td_samplesperpixel : 1); switch (td->td_bitspersample) { case 8: sp->hordiff = pred8bit; break; case 16: sp->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->hordiff != NULL) { /* * Calculate the scanline/tile-width size in bytes. */ if (isTiled(tif)) sp->rowsize = TIFFTileRowSize(tif); else sp->rowsize = TIFFScanlineSize(tif); } else sp->rowsize = 0; return (1); } /* * 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) #endif #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: ; \ } #define XREPEAT4(n, op) \ switch (n) { \ default: { int i; for (i = n-4; i > 0; i--) { op; } } \ case 2: op; \ case 1: op; \ case 0: ; \ } static void DECLARE3(horizontalAccumulate8, register char*, cp, register u_long, cc, register int, stride ) { if (cc > stride) { cc -= stride; /* * Pipeline the most common cases. */ if (stride == 3) { u_int cr = cp[0]; u_int cg = cp[1]; u_int cb = cp[2]; do { cc -= 3, cp += 3; cp[0] = (cr += cp[0]); cp[1] = (cg += cp[1]); cp[2] = (cb += cp[2]); } while ((long)cc > 0); } else if (stride == 4) { u_int cr = cp[0]; u_int cg = cp[1]; u_int cb = cp[2]; u_int ca = cp[3]; do { cc -= 4, cp += 4; cp[0] = (cr += cp[0]); cp[1] = (cg += cp[1]); cp[2] = (cb += cp[2]); cp[3] = (ca += cp[3]); } while ((long)cc > 0); } else { do { XREPEAT4(stride, cp[stride] += *cp; cp++) cc -= stride; } while ((long)cc > 0); } } } static void DECLARE3(horizontalAccumulate16, char*, cp, u_long, cc, register int, stride) { register short* wp = (short *)cp; register u_long 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 DECLARE1(LZWPreDecode, TIFF*, tif) { register LZWDecodeState *sp = (LZWDecodeState *)tif->tif_data; if (sp == NULL) { tif->tif_data = _TIFFmalloc(sizeof (LZWDecodeState)); if (tif->tif_data == NULL) { TIFFError("LZWPreDecode", "No space for LZW state block"); return (0); } sp = (LZWDecodeState *)tif->tif_data; sp->dec_decode = NULL; if (!LZWCheckPredictor(tif, &sp->base, 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; } /* * Pre-load the table. */ { int code; for (code = 255; code >= 0; code--) { sp->dec_codetab[code].value = code; sp->dec_codetab[code].firstchar = code; sp->dec_codetab[code].length = 1; sp->dec_codetab[code].next = 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) { if (sp->lzw_hordiff == NULL) { /* * 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; } TIFFWarning(tif->tif_name, "Old-style LZW codes, convert file"); } sp->lzw_maxcode = MAXCODE(BITS_MIN); sp->dec_decode = LZWDecodeCompat; #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_rawdatasize << 3; #endif sp->dec_free_entp = sp->dec_codetab + CODE_FIRST; 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 = (nextdata >> (nextbits-nbits)) & nbitsmask; \ nextbits -= nbits; \ } static void DECLARE1(codeLoop, TIFF*, tif) { TIFFError(tif->tif_name, "LZWDecode: Bogus encoding, loop in the code table; scanline %d", tif->tif_row); } static int DECLARE4(LZWDecode, TIFF*, tif, u_char*, op0, u_long, occ0, u_int, s) { LZWDecodeState *sp = (LZWDecodeState *)tif->tif_data; char *op = (char *)op0; long occ = (long)occ0; char *tp; u_char *bp; int code, nbits, nextbits, len; long nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; assert(sp != NULL); /* * Restart interrupted output operation. */ if (sp->dec_restart) { int 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++ = 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++ = code, occ--; } tif->tif_rawcp = (char *)bp; sp->lzw_nbits = 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 |= *(bp)++ << nextbits; \ nextbits += 8; \ if (nextbits < nbits) { \ nextdata |= *(bp)++ << nextbits; \ nextbits += 8; \ } \ code = nextdata & nbitsmask; \ nextdata >>= nbits; \ nextbits -= nbits; \ } static DECLARE4(LZWDecodeCompat, TIFF*, tif, u_char*, op0, u_long, occ0, u_int, s) { LZWDecodeState *sp = (LZWDecodeState *)tif->tif_data; char *op = (char *)op0; long occ = occ0; char *tp; u_char *bp; int code, nbits, nextbits; long nextdata, nbitsmask; code_t *codep, *free_entp, *maxcodep, *oldcodep; assert(sp != NULL); /* * Restart interrupted output operation. */ if (sp->dec_restart) { int 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); tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); return (1); } /* * Residue satisfies only part of the decode request. */ op += residue, occ -= residue; tp = op; do { *--tp = codep->value; codep = codep->next; } while (--residue); 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, GetNextCodeCompat); 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; NextCode(tif, sp, bp, code, GetNextCodeCompat); if (code == CODE_EOI) break; *op++ = 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; } 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->length > occ); sp->dec_restart = occ; tp = op + occ; do { *--tp = codep->value; codep = codep->next; } while (--occ); break; } op += codep->length, occ -= codep->length; tp = op; do { *--tp = codep->value; } while (codep = codep->next); } else *op++ = code, occ--; } tif->tif_rawcp = (char *)bp; sp->lzw_nbits = 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, "LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)", tif->tif_row, occ); return (0); } return (1); } #endif /* LZW_COMPAT */ /* * Decode a scanline and apply the predictor routine. */ static DECLARE4(LZWDecodePredRow, TIFF*, tif, u_char*, op0, u_long, occ0, u_int, s) { LZWDecodeState *sp = (LZWDecodeState *)tif->tif_data; assert(sp != NULL); assert(sp->dec_decode != NULL); if ((*sp->dec_decode)(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 DECLARE4(LZWDecodePredTile, TIFF*, tif, u_char*, op0, u_long, occ0, u_int, s) { LZWDecodeState *sp = (LZWDecodeState *)tif->tif_data; u_long rowsize; assert(sp != NULL); assert(sp->dec_decode != NULL); if (!(*sp->dec_decode)(tif, op0, occ0, s)) return (0); rowsize = sp->lzw_rowsize; assert(rowsize > 0); while ((long)occ0 > 0) { (*sp->lzw_hordiff)((char*)op0, rowsize, sp->lzw_stride); occ0 -= rowsize; op0 += rowsize; } return (1); } /* * LZW Encoding. */ static void DECLARE3(horizontalDifference8, register char*, cp, register u_long, cc, register int, stride ) { if (cc > stride) { cc -= stride; /* * Pipeline the most common cases. */ if (stride == 3) { int r1, g1, b1; int r2 = cp[0]; int g2 = cp[1]; int b2 = cp[2]; do { r1 = cp[3]; cp[3] = r1-r2; r2 = r1; g1 = cp[4]; cp[4] = g1-g2; g2 = g1; b1 = cp[5]; cp[5] = b1-b2; b2 = b1; cp += 3; } while ((long)(cc -= 3) > 0); } else if (stride == 4) { int r1, g1, b1, a1; int r2 = cp[0]; int g2 = cp[1]; int b2 = cp[2]; int a2 = cp[3]; do { r1 = cp[4]; cp[4] = r1-r2; r2 = r1; g1 = cp[5]; cp[5] = g1-g2; g2 = g1; b1 = cp[6]; cp[6] = b1-b2; b2 = b1; a1 = cp[7]; cp[7] = a1-a2; a2 = a1; cp += 4; } while ((long)(cc -= 4) > 0); } else { cp += cc - 1; do { REPEAT4(stride, cp[stride] -= cp[0]; cp--) } while ((long)(cc -= stride) > 0); } } } static void DECLARE3(horizontalDifference16, char*, cp, u_long, cc, register int, stride ) { register short *wp = (short *)cp; register u_long 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 DECLARE1(LZWPreEncode, TIFF*, tif) { register LZWEncodeState *sp = (LZWEncodeState *)tif->tif_data; if (sp == NULL) { tif->tif_data = _TIFFmalloc(sizeof (LZWEncodeState)); if (tif->tif_data == NULL) { TIFFError("LZWPreEncode", "No space for LZW state block"); return (0); } sp = (LZWEncodeState *)tif->tif_data; if (!LZWCheckPredictor(tif, &sp->base, horizontalDifference8, horizontalDifference16)) return (0); if (sp->lzw_hordiff != NULL) { tif->tif_encoderow = LZWEncodePredRow; tif->tif_encodestrip = LZWEncodePredTile; tif->tif_encodetile = LZWEncodePredTile; } } sp->lzw_nbits = BITS_MIN; sp->lzw_maxcode = MAXCODE(BITS_MIN); sp->lzw_free_ent = CODE_FIRST; sp->lzw_nextbits = 0; sp->lzw_nextdata = 0; sp->enc_checkpoint = CHECK_GAP; sp->enc_ratio = 0; sp->enc_incount = 0; sp->enc_outcount = 0; /* * The 4 here insures there is space for 2 max-sized * codes in LZWEncode and LZWPostDecode. */ sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4; cl_hash(sp); /* clear hash table */ sp->enc_oldcode = -1; /* generates CODE_CLEAR in LZWEncode */ return (1); } #define CALCRATIO(sp, rat) { \ if (incount > 0x007fffff) { /* NB: shift will overflow */\ rat = outcount >> 8; \ rat = (rat == 0 ? 0x7fffffff : incount/rat); \ } else \ rat = (incount<<8) / outcount; \ } #define PutNextCode(op, c) { \ nextdata = (nextdata << nbits) | c; \ nextbits += nbits; \ *op++ = nextdata >> (nextbits-8); \ nextbits -= 8; \ if (nextbits >= 8) { \ *op++ = nextdata >> (nextbits-8); \ nextbits -= 8; \ } \ outcount += nbits; \ } /* * Encode a chunk 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 DECLARE4(LZWEncode, TIFF*, tif, u_char*, bp, u_long, cc, u_int, s) { register LZWEncodeState *sp = (LZWEncodeState *)tif->tif_data; register long fcode; register hash_t *hp; register int h, c, ent, disp; long incount, outcount, checkpoint; long nextdata, nextbits; int free_ent, maxcode, nbits; char *op, *limit; if (sp == NULL) return (0); /* * Load local state. */ incount = sp->enc_incount; outcount = sp->enc_outcount; checkpoint = sp->enc_checkpoint; nextdata = sp->lzw_nextdata; nextbits = sp->lzw_nextbits; free_ent = sp->lzw_free_ent; maxcode = sp->lzw_maxcode; nbits = sp->lzw_nbits; op = tif->tif_rawcp; limit = sp->enc_rawlimit; ent = sp->enc_oldcode; if (ent == -1 && cc > 0) { /* * NB: This is safe because it can only happen * at the start of a strip where we know there * is space in the data buffer. */ PutNextCode(op, CODE_CLEAR); ent = *bp++; cc--; incount++; } while (cc > 0) { c = *bp++; cc--; incount++; fcode = ((long)c << BITS_MAX) + ent; h = (c << HSHIFT) ^ ent; /* xor hashing */ hp = &sp->enc_hashtab[h]; if (hp->hash == fcode) { ent = hp->code; continue; } if (hp->hash >= 0) { /* * Primary hash failed, check secondary hash. */ disp = HSIZE - h; if (h == 0) disp = 1; do { if ((hp -= disp) < sp->enc_hashtab) hp += HSIZE; if (hp->hash == fcode) { ent = hp->code; goto hit; } } while (hp->hash >= 0); } /* * New entry, emit code and add to table. */ /* * Verify there is space in the buffer for the code * and any potential Clear code that might be emitted * below. The value of limit is setup so that there * are at least 4 bytes free--room for 2 codes. */ if (op > limit) { tif->tif_rawcc = op - tif->tif_rawdata; TIFFFlushData1(tif); op = tif->tif_rawdata; } PutNextCode(op, ent); ent = c; hp->code = free_ent++; hp->hash = fcode; if (free_ent == CODE_MAX-1) { /* table is full, emit clear code and reset */ cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else { /* * If the next entry is going to be too big for * the code size, then increase it, if possible. */ if (free_ent > maxcode) { nbits++; assert(nbits <= BITS_MAX); maxcode = MAXCODE(nbits); } else if (incount >= checkpoint) { long rat; /* * Check compression ratio and, if things seem * to be slipping, clear the hash table and * reset state. The compression ratio is a * 24+8-bit fractional number. */ checkpoint = incount+CHECK_GAP; CALCRATIO(sp, rat); if (rat <= sp->enc_ratio) { cl_hash(sp); sp->enc_ratio = 0; incount = 0; outcount = 0; free_ent = CODE_FIRST; PutNextCode(op, CODE_CLEAR); nbits = BITS_MIN; maxcode = MAXCODE(BITS_MIN); } else sp->enc_ratio = rat; } } hit: ; } /* * Restore global state. */ sp->enc_incount = incount; sp->enc_outcount = outcount; sp->enc_checkpoint = checkpoint; sp->enc_oldcode = ent; sp->lzw_nextdata = nextdata; sp->lzw_nextbits = nextbits; sp->lzw_free_ent = free_ent; sp->lzw_maxcode = maxcode; sp->lzw_nbits = nbits; tif->tif_rawcp = op; return (1); } static DECLARE4(LZWEncodePredRow, TIFF*, tif, u_char*, bp, u_long, cc, u_int, s) { LZWEncodeState *sp = (LZWEncodeState *)tif->tif_data; assert(sp != NULL); assert(sp->lzw_hordiff != NULL); /* XXX horizontal differencing alters user's data XXX */ (*sp->lzw_hordiff)((char *)bp, cc, sp->lzw_stride); return (LZWEncode(tif, bp, cc, s)); } static DECLARE4(LZWEncodePredTile, TIFF*, tif, u_char*, bp0, u_long, cc0, u_int, s) { LZWEncodeState *sp = (LZWEncodeState *)tif->tif_data; u_long cc = cc0, rowsize; u_char *bp = bp0; assert(sp != NULL); assert(sp->lzw_hordiff != NULL); rowsize = sp->lzw_rowsize; assert(rowsize > 0); while ((long)cc > 0) { (*sp->lzw_hordiff)((char *)bp, rowsize, sp->lzw_stride); cc -= rowsize; bp += 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 DECLARE1(LZWPostEncode, TIFF*, tif) { register LZWEncodeState *sp = (LZWEncodeState *)tif->tif_data; char *op = tif->tif_rawcp; long nextbits = sp->lzw_nextbits; long nextdata = sp->lzw_nextdata; long outcount = sp->enc_outcount; int nbits = sp->lzw_nbits; if (op > sp->enc_rawlimit) { tif->tif_rawcc = op - tif->tif_rawdata; TIFFFlushData1(tif); op = tif->tif_rawdata; } if (sp->enc_oldcode != -1) { PutNextCode(op, sp->enc_oldcode); sp->enc_oldcode = -1; } PutNextCode(op, CODE_EOI); if (nextbits > 0) *op++ = nextdata << (8-nextbits); tif->tif_rawcc = op - tif->tif_rawdata; return (1); } /* * Reset encoding hash table. */ static void DECLARE1(cl_hash, LZWEncodeState*, sp) { register hash_t *hp = &sp->enc_hashtab[HSIZE-1]; register long i = HSIZE-8; do { i -= 8; hp[-7].hash = -1; hp[-6].hash = -1; hp[-5].hash = -1; hp[-4].hash = -1; hp[-3].hash = -1; hp[-2].hash = -1; hp[-1].hash = -1; hp[ 0].hash = -1; hp -= 8; } while (i >= 0); for (i += 8; i > 0; i--, hp--) hp->hash = -1; } static DECLARE1(LZWCleanup, TIFF*, tif) { if (tif->tif_data) { _TIFFfree(tif->tif_data); tif->tif_data = NULL; } } int DECLARE1(TIFFInitLZW, 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); } /* * 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.