#define DUMMY \
set -ex; \
g++ -DNDEBUG=1 -O3 -ansi -pedantic \
 -Wall -W -Wstrict-prototypes -Wtraditional -Wnested-externs -Winline \
 -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wmissing-prototypes \
 -Wmissing-declarations pts_lzw.c -c; \
exit
/* pts_lzw.c -- a real, effective implementation of PostScript
*   LanguageLevel2 and PDF /LZWEncode and /LZWDecode filters (same as the LZW
*   compression used in TIFF raster image files)
*
* based on tif_lzw.c in libtiff-v3.4beta037 by Sam Leffler and Silicon Graphics.
* by [email protected] at Sun Dec 30 15:04:19 CET 2001
* encoding and decoding works at Sun Dec 30 17:05:23 CET 2001
* modified for sam2p at Mon Mar  4 00:21:59 CET 2002
*
* Note that the LZW compression (but not uncompression) is patented by
* Unisys (patent number #4,558,302), so use this program at your own legal
* risk!
*
* Predictors and PostScript LanguageLevel3 filter options are not supported.
*
* Test: linux-2.2.8.tar.gz
* -- uncompressed:              58 388 480 bytes
* -- LZWEncode (lzw_codec.c):   26 518 397 bytes (uncompression OK)
* -- FlateEncode (almost gzip): 13 808 890 bytes (uncompression: zcat)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/* Imp: check #ifdef _WINDOWS */
/* Dat: a strip is an interval of rows. Each strip -- probably except for the
*      last -- has a same number of rows. Strips are useful for TIFF writers
*      to better organize data in memory or disk.
*/

#ifdef __GNUC__
#ifndef __clang__
#pragma implementation
#endif
#endif

#if _MSC_VER > 1000
# undef  __PROTOTYPES__
# define __PROTOTYPES__ 1
# pragma warning(disable: 4127) /* conditional expression is constant */
# pragma warning(disable: 4244) /* =' : conversion from 'int ' to 'unsigned char ', possible loss of data */
#endif


/* Original: /d1/sam/tiff/libtiff/RCS/tif_lzw.c,v 1.73 1997/08/29 21:45:54 sam 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.
*/

/**** pts ****/
#if OBJDEP
#  warning PROVIDES: pts_lzw
#endif
#define LZW_SUPPORT 1
#if 0 /* conflicts with some system defs */
typedef unsigned short u_short;
typedef unsigned char u_char;
typedef unsigned long u_long;
#endif
#define TO_RDONLY 1
#define _TIFFmalloc malloc
#define _TIFFfree free
#define _TIFFmemset memset
#include <stdlib.h>
#include <string.h>

/*
* ``Library-private'' definitions.
*/

/*
* TIFF I/O Library Definitions.
*/
/*
* Tag Image File Format (TIFF)
*
* Based on Rev 6.0 from:
*    Developer's Desk
*    Aldus Corporation
*    411 First Ave. South
*    Suite 200
*    Seattle, WA  98104
*    206-622-5500
*/
#define TIFF_VERSION    42

/*
* NB: In the comments below,
*  - items marked with a + are obsoleted by revision 5.0,
*  - items marked with a ! are introduced in revision 6.0.
*  - items marked with a % are introduced post revision 6.0.
*  - items marked with a $ are obsoleted by revision 6.0.
*/

/* --- */

/*
* This define can be used in code that requires
* compilation-related definitions specific to a
* version or versions of the library.  Runtime
* version checking should be done based on the
* string returned by TIFFGetVersion.
*/
#define TIFFLIB_VERSION 19970127        /* January 27, 1997 */

/*
* The following typedefs define the intrinsic size of
* data types used in the *exported* interfaces.  These
* definitions depend on the proper definition of types
* in tiff.h.  Note also that the varargs interface used
* to pass tag types and values uses the types defined in
* tiff.h directly.
*
* NB: ttag_t is unsigned int and not unsigned short because
*     ANSI C requires that the type before the ellipsis be a
*     promoted type (i.e. one of int, unsigned int, pointer,
*     or double) and because we defined pseudo-tags that are
*     outside the range of legal Aldus-assigned tags.
* NB: tsize_t is int32 and not uint32 because some functions
*     return -1.
* NB: toff_t is not off_t for many reasons; TIFFs max out at
*     32-bit file offsets being the most important
*/

#ifndef NULL
#define NULL    0
#endif

typedef struct pts_lzw_state TIFF;
#include "pts_lzw.h"

/**** pts ****/
static  int TIFFInitLZW(TIFF*);
static void TIFFError(char const*a, char const*b);
#if 0 /**** pts ****/
static void TIFFWarning(char const*a, char const*b, int c);
void TIFFWarning(char const*a, char const*b, int c) {
 fprintf(stderr, "Warning: %s: ", a);
 fprintf(stderr, b, c);
 fprintf(stderr, "\n");
}
#endif
static  int TIFFAppendTo(TIFF*, tidataval_t*, tsize_t); /* tif_write.h */
#if 0
static void TIFFReverseBits(unsigned char *, unsigned long);
#endif

#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 <assert.h>
/* #include <stdio.h> */

/*
* Internal version of TIFFFlushData that can be
* called by ``encodestrip routines'' w/o concern
* for infinite recursion.
*/
static int
TIFFFlushData1(TIFF* tif)
{
       if (tif->tif_rawcc > 0) {
#if 0
               if (tif->tif_revbits_p)
                       TIFFReverseBits((unsigned char *)tif->tif_rawdata,
                           tif->tif_rawcc);
#endif
               if (!TIFFAppendTo(tif,
                   /* isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip, */
                   tif->tif_rawdata, tif->tif_rawcc))
                       return (0);
               tif->tif_rawcc = 0;
               tif->tif_rawcp = tif->tif_rawdata;
       }
       return (1);
}



/*
* 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 */
#undef LZW_CHECKEOS /**** pts ****/

#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 {
#if 0 /****pts****/
       TIFFPredictorState predict;     /* predictor super class */
#endif

       unsigned short          nbits;          /* # of bits/code */
       unsigned short          maxcode;        /* maximum code for lzw_nbits */
       unsigned short          free_ent;       /* next free entry in hash table */
       long            nextdata;       /* next bits of i/o */
       long            nextbits;       /* # of valid bits in lzw_nextdata */
} 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;
       unsigned short  length;                 /* string len, including this token */
       unsigned char   value;                  /* data value */
       unsigned char   firstchar;              /* first token of string */
} code_t;

typedef int (*decodeFunc)(TIFF*, tidataval_t*, tsize_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 unsigned short 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 */
       tidataval_t* enc_rawlimit;      /* bound on tif_rawdata buffer */
       hash_t* enc_hashtab;            /* kept separate for small machines */
} LZWEncodeState;

#define LZWState(tif)           ((LZWBaseState*)  (void*) (tif)->tif_data)
#define DecoderState(tif)       ((LZWDecodeState*)(void*) LZWState(tif))
#define EncoderState(tif)       ((LZWEncodeState*)(void*) LZWState(tif))
/* ^^^ Dat: (void*) -> suppress gcc warning from -Wcast-align */

static  void cl_hash(LZWEncodeState*);

#if 0 /**** pts ****/ /* LZW decoder is not needed */

static  int LZWDecode(TIFF*, tidataval_t*, tsize_t);
#ifdef LZW_COMPAT
static  int LZWDecodeCompat(TIFF*, tidataval_t*, tsize_t);
#endif

/*
* 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*/ 0);                          \
               _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

static int
LZWSetupDecode(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.
                */
               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;
               }
       }
       return (1);
}

/*
* Setup state for decoding a strip.
*/
static int
LZWPreDecode(TIFF* tif)
{
       LZWDecodeState *sp = DecoderState(tif);

       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 %d", 0);
#if 0 /**** pts ****/
                       /*
                        * 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);
#endif
                       LZWSetupDecode(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 void
codeLoop(TIFF* tif)
{
       TIFFError(tif->tif_name,
           "LZWDecode: Bogus encoding, loop in the code table; scanline %d"
           /*,tif->tif_row*/);
}

static int
LZWDecode(TIFF* tif, tidataval_t* op0, tsize_t occ0)
{
       LZWDecodeState *sp = DecoderState(tif);
       char *op = (char*) op0;
       long occ = (long) occ0;
       char *tp;
       unsigned char *bp;
       hcode_t code;
       int len;
       long nbits, nextbits, nextdata, nbitsmask;
       code_t *codep, *free_entp, *maxcodep, *oldcodep;

       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 occ0-occ;
               }
               /*
                * 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 = (unsigned char *)tif->tif_rawcp; /* reading from here */
       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 && bp<tif->tif_rawend /**** pts ****/) {
               NextCode(tif, sp, bp, code, GetNextCode);
               #if 0
                 if (bp>tif->tif_rawend) fprintf(stderr, "over %d\n", tif->tif_rawend-bp);
                 assert(bp<=tif->tif_rawend);
               #endif
               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;

#if 1 /**** pts ****/
                       NextCode(tif, sp, bp, code, GetNextCode);
                       if (code == CODE_EOI)
                               break;
                       *op++ = code, occ--;
                       oldcodep = sp->dec_codetab + code; /* ! */
#endif
                       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);
                                               return -1;
                                       }
                               }
                               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);
                           return -1;
                           /* break; */
                       }
                       op += len, occ -= len;
               } else
                       *op++ = code, occ--;
       }

       tif->tif_rawcp = (tidataval_t*) bp;
       sp->lzw_nbits = (unsigned 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 0 /**** pts ****/
       if (occ > 0) {
               TIFFError(tif->tif_name,
               "LZWDecode: Not enough data at scanline %d (short %d bytes)"
                   /*,tif->tif_row, occ*/);
               return (0);
       }
#endif
       return occ0-occ;
}

#ifdef LZW_COMPAT
/*
* Decode a "hunk of data" for old images.
*/
#define GetNextCodeCompat(sp, bp, code) {                       \
       nextdata |= (unsigned long) *(bp)++ << nextbits;                \
       nextbits += 8;                                          \
       if (nextbits < nbits) {                                 \
               nextdata |= (unsigned long) *(bp)++ << nextbits;        \
               nextbits += 8;                                  \
       }                                                       \
       code = (hcode_t)(nextdata & nbitsmask);                 \
       nextdata >>= nbits;                                     \
       nextbits -= nbits;                                      \
}

static int
LZWDecodeCompat(TIFF* tif, tidataval_t* op0, tsize_t occ0)
{
       LZWDecodeState *sp = DecoderState(tif);
       char *op = (char*) op0;
       long occ = (long) occ0;
       char *tp;
       unsigned char *bp;
       int code, nbits;
       long nextbits, nextdata, nbitsmask;
       code_t *codep, *free_entp, *maxcodep, *oldcodep;

       assert(0);
       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);
                       tp = op + occ;
                       do {
                               *--tp = codep->value;
                               codep = codep->next;
                       } while (--occ);
                       return occ0-occ;
               }
               /*
                * 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 = (unsigned 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 && bp<tif->tif_rawend) {
               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 (0!=(codep = codep->next));
               } else
                       *op++ = code, occ--;
       }

       tif->tif_rawcp = (tidataval_t*) 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 0 /**** pts ****/
       if (occ > 0) {
               TIFFError(tif->tif_name,
                   "LZWDecodeCompat: Not enough data at scanline %d (short %d bytes)"
                   /*,tif->tif_row, occ*/);
               return (0);
       }
#endif
       return occ0-occ;
}
#endif /* LZW_COMPAT */

#endif /**** pts ****/

/* --- */

/*
* LZW Encoding.
*/

static int
LZWSetupEncode(TIFF* tif)
{
       LZWEncodeState* sp = EncoderState(tif);
       static const char module[] = "LZWSetupEncode";

       assert(sp != NULL);
       sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t));
       if (sp->enc_hashtab == NULL) {
               TIFFError(module, "No space for LZW hash table");
               return (0);
       }
       return (1);
}

/*
* Reset encoding state at the start of a strip.
*/
static int
LZWPreEncode(TIFF* tif)
{
       LZWEncodeState *sp = EncoderState(tif);

       assert(sp != NULL);
       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 = (hcode_t) -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++ = (unsigned char)(nextdata >> (nextbits-8));              \
       nextbits -= 8;                                          \
       if (nextbits >= 8) {                                    \
               *op++ = (unsigned char)(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 int
LZWEncode(TIFF* tif, tidataval_t* bp, tsize_t cc)
{
       register LZWEncodeState *sp = EncoderState(tif);
       register long fcode;
       register hash_t *hp;
       register int h, c;
       hcode_t ent;
       long disp;
       long incount, outcount, checkpoint;
       long nextdata, nextbits;
       int free_ent, maxcode, nbits;
       tidataval_t* 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 == (hcode_t) -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 */
#ifdef _WINDOWS /* ?? */
               /*
                * Check hash index for an overflow.
                */
               if (h >= HSIZE)
                       h -= HSIZE;
#endif
               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 {
                               /*
                                * Avoid pointer arithmetic 'cuz of
                                * wraparound problems with segments.
                                */
                               if ((h -= disp) < 0)
                                       h += HSIZE;
                               hp = &sp->enc_hashtab[h];
                               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 = (tsize_t)(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 = (int) 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);
}

/*
* Finish off an encoded strip by flushing the last
* string and tacking on an End Of Information code.
*/
static int
LZWPostEncode(TIFF* tif)
{
       register LZWEncodeState *sp = EncoderState(tif);
       tidataval_t* 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) {
               /* fprintf(stderr, "Yupp!\n"); */
               tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata);
               TIFFFlushData1(tif);
               op = tif->tif_rawdata;
       }
       if (sp->enc_oldcode != (hcode_t) -1) {
               /* fprintf(stderr, "EIK\n"); */
               PutNextCode(op, sp->enc_oldcode);
               sp->enc_oldcode = (hcode_t) -1;
       }
       PutNextCode(op, CODE_EOI);
       if (nextbits > 0)
               *op++ = (unsigned char)(nextdata << (8-nextbits));
       tif->tif_rawcc = (tsize_t)(op - tif->tif_rawdata);
       return (1);
}

/*
* Reset encoding hash table.
*/
static void
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 void
LZWCleanup(TIFF* tif)
{
       if (tif->tif_data) {
               if (tif->tif_reading_p) {
                       if (DecoderState(tif)->dec_codetab)
                               _TIFFfree(DecoderState(tif)->dec_codetab);
               } else {
                       if (EncoderState(tif)->enc_hashtab)
                               _TIFFfree(EncoderState(tif)->enc_hashtab);
               }
               _TIFFfree(tif->tif_data);
               tif->tif_data = NULL;
       }
       _TIFFfree(tif->tif_rawdata);
}

static int
TIFFInitLZW(TIFF* tif)
{
       /* assert(scheme == COMPRESSION_LZW); */
       /*
        * Allocate state block so tag methods have storage to record values.
        */
       if (tif->tif_reading_p) {
               tif->tif_data = (tidataval_t*) _TIFFmalloc(sizeof (LZWDecodeState));
               if (tif->tif_data == NULL)
                       goto bad;
               DecoderState(tif)->dec_codetab = NULL;
               DecoderState(tif)->dec_decode = NULL;
       } else {
               tif->tif_data = (tidataval_t*) _TIFFmalloc(sizeof (LZWEncodeState));
               if (tif->tif_data == NULL)
                       goto bad;
               EncoderState(tif)->enc_hashtab = NULL;
       }
#if 0 /**** pts ****/
       /*
        * Install codec methods.
        */
       tif->tif_setupdecode = LZWSetupDecode;
       tif->tif_predecode = LZWPreDecode;
       tif->tif_decoderow = LZWDecode;
       tif->tif_decodestrip = LZWDecode;
       tif->tif_decodetile = LZWDecode;
       tif->tif_setupencode = LZWSetupEncode;
       tif->tif_preencode = LZWPreEncode;
       tif->tif_postencode = LZWPostEncode;
       tif->tif_encoderow = LZWEncode;
       tif->tif_encodestrip = LZWEncode;
       tif->tif_encodetile = LZWEncode;
       tif->tif_cleanup = LZWCleanup;
#endif
#if 0 /**** pts ****/
       /*
        * Setup predictor setup.
        */
       (void) TIFFPredictorInit(tif);
#endif
       return (1);
bad:
       TIFFError("TIFFInitLZW", "No space for LZW state block");
       return (0);
}

/*
* 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.
*/
#endif /* LZW_SUPPORT */

#if 0
#ifdef __cplusplus
extern "C"
#else
extern
#endif
FILE *fdopen (int fildes, const char *mode); /* POSIX, but not ANSI */
#else
#undef  _POSIX_SOURCE
#define _POSIX_SOURCE 1
#undef  _POSIX_C_SOURCE /* Sat Jun  1 14:25:53 CEST 2002 */
#define _POSIX_C_SOURCE 2
#include <stdio.h>
#endif

#if 0 /**** pts: never needed, because output FillOrder is always 1 */
void
TIFFReverseBits(register unsigned char* cp, register unsigned long n)
{
       char *TIFFBitRevTable=...; /**** pts ****/
       for (; n > 8; n -= 8) {
               cp[0] = TIFFBitRevTable[cp[0]];
               cp[1] = TIFFBitRevTable[cp[1]];
               cp[2] = TIFFBitRevTable[cp[2]];
               cp[3] = TIFFBitRevTable[cp[3]];
               cp[4] = TIFFBitRevTable[cp[4]];
               cp[5] = TIFFBitRevTable[cp[5]];
               cp[6] = TIFFBitRevTable[cp[6]];
               cp[7] = TIFFBitRevTable[cp[7]];
               cp += 8;
       }
       while (n-- > 0)
               *cp = TIFFBitRevTable[*cp], cp++;
}
#endif

static void TIFFError(char const*a, char const*b) {
 fprintf(stderr, "%s: %s\n", a, b);
}
static int TIFFAppendTo(TIFF*tif, tidataval_t* data, tsize_t cc) {
  (void)tif;
  (void)data;
  (void)cc;
  /* fwrite(data, 1, cc, (FILE*)tif->tif_sout);
     if (ferror((FILE*)tif->tif_sout)) return 0; */
  if (-1==tif->tif_writer((char*)data, cc, tif->tif_sout)) return 0;
#if 0 /**** pts ****/ /* tif_write.h */
  (void)strip;
       TIFFDirectory *td = &tif->tif_dir;
       static const char module[] = "TIFFAppendToStrip";

       if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
               /*
                * No current offset, set the current strip.
                */
               if (td->td_stripoffset[strip] != 0) {
                       if (!SeekOK(tif, td->td_stripoffset[strip])) {
                               TIFFError(module,
                                   "%s: Seek error at scanline %lu",
                                   tif->tif_name, (unsigned long) tif->tif_row);
                               return (0);
                       }
               } else
                       td->td_stripoffset[strip] =
                           TIFFSeekFile(tif, (toff_t) 0, SEEK_END);
               tif->tif_curoff = td->td_stripoffset[strip];
       }
       if (!WriteOK(tif, data, cc)) {
               TIFFError(module, "%s: Write error at scanline %lu",
                   tif->tif_name, (unsigned long) tif->tif_row);
               return (0);
       }
       tif->tif_curoff += cc;
       td->td_stripbytecount[strip] += cc;
#endif
       return (1);
}

#if 0
static tidataval_t readbuf[4096];
unsigned int readlen;
static char *inname;
typedef int (*filter_t)(FILE *sin, FILE*sout);
/** /LZWEncode filter, STDIN -> STDOUT */
static int lzw_encode(FILE *sin, FILE *sout) {
 TIFF tif;
 tif.tif_sout=sout;
 tif.tif_reading_p=0;
#if 0
 tif.tif_revbits_p=0;
#endif
 tif.tif_name=inname;
 tif.tif_rawdata=(tidataval_t*)_TIFFmalloc(tif.tif_rawdatasize=4096); /* Imp: check */
 tif.tif_rawcp=tif.tif_rawdata;
 tif.tif_rawcc=0;
 if (TIFFInitLZW(&tif) &&
     LZWSetupEncode(&tif) &&
     LZWPreEncode(&tif) /* for each strip */) {
   while ((readlen=fread(readbuf, 1, sizeof(readbuf), sin))!=0) {
     if (!LZWEncode(&tif, readbuf, readlen)) goto err;
     /* fprintf(stderr, "readlen=%d\n", readlen); */
   }
   if (!LZWPostEncode(&tif)) goto err; /* for each strip */
   LZWCleanup(&tif);
   if (!TIFFFlushData1(&tif)) { _TIFFfree(tif.tif_rawdata); fflush(sout); return 0; }
   fflush(sout);
 } else { err:
   fflush(sout);
   LZWCleanup(&tif);
   _TIFFfree(tif.tif_rawdata);
   return 0;
 }
 return 1;
}
/** /LZWEncode filter, STDIN -> STDOUT */
static int lzw_decode(FILE *sin, FILE *sout) {
 TIFF tif;
 /* tidataval_t *rawend0; */
 /* char *xbuf; */
 int got;
 unsigned int left;
 tif.tif_reading_p=1;
#if 0
 tif.tif_revbits_p=0;
#endif
 tif.tif_name=inname;
 tif.tif_rawdata=(tidataval_t*)_TIFFmalloc(tif.tif_rawdatasize=4096); /* Imp: check */
 tif.tif_rawcc=0;
 left=0;
 if (TIFFInitLZW(&tif) &&
     LZWSetupDecode(&tif) &&
     LZWPreDecode(&tif) /* for each strip */) {
   /* vvv Dat: fread returns >=0 ! */
   while ((readlen=left+fread(tif.tif_rawdata+left, 1, tif.tif_rawdatasize-left, sin))!=0) {
    #if DEBUGMSG
     fprintf(stderr, "readlen+=%d\n", readlen);
    #endif
     while (readlen<=3) {
       if ((got=fread(tif.tif_rawdata+readlen, 1, tif.tif_rawdatasize-readlen, sin))==0) {
         tif.tif_rawend=tif.tif_rawdata+readlen;
         goto star;
       }
       readlen+=got;
     }
     tif.tif_rawend=tif.tif_rawdata+readlen-3;
    star:
     tif.tif_rawcp=tif.tif_rawdata;
    #if DEBUGMSG
     fprintf(stderr, "readlen:=%d\n", readlen);
    #endif
     while (1) {
       if (-1==(got=(DecoderState(&tif)->dec_decode)(&tif, readbuf, sizeof(readbuf)))) goto err;
      #if DEBUGMSG
       fprintf(stderr, "OK, written: %d %d\n", got, tif.tif_rawend-tif.tif_rawcp);
      #endif
       if (0==got) break;
       fwrite(readbuf, 1, got, sout);
     }
     left=tif.tif_rawdata+readlen-tif.tif_rawcp;
     got=left;
    #if DEBUGMSG
     fprintf(stderr, "left=%d\n", left); fflush(stderr);
    #endif
     while (got--!=0) { tif.tif_rawdata[got]=tif.tif_rawcp[got]; }
   }
#if 0
   if (!LZWPostDecode(&tif)) { LZWCleanup(&tif); return 0; } /* for each strip */
#endif
   LZWCleanup(&tif);
   fflush(sout);
 } else { err:
   fflush(sout);
   LZWCleanup(&tif);
   _TIFFfree(tif.tif_rawdata);
   return 0;
 }
 return 1;
}
#endif

static int feeder(char *readbuf, unsigned readlen, TIFF *tif) {
 /*(void)LZWPreDecode;*/ /* Imp: better avoid gcc warning... */
 if (readlen!=0) {
   if (!LZWEncode(tif, (tidataval_t*)readbuf, readlen)) { e1:
     LZWCleanup(tif); e2:
     _TIFFfree(tif->tif_rawdata);
     return 0;
   }
 } else {
   if (!LZWPostEncode(tif)) goto e1;
   if (!TIFFFlushData1(tif)) goto e2;
   LZWCleanup(tif);
 }
 return 1;
}

/** /LZWEncode filter, STDIN -> STDOUT */
int pts_lzw_init(TIFF *tif) {
 /* tif_sout and tif_writer are already filled */
 tif->tif_feeder=feeder;
 tif->tif_reading_p=0;
#if 0
 tif->tif_revbits_p=0;
#endif
 tif->tif_name="//.filter";/*inname;*/
 tif->tif_rawdata=(tidataval_t*)_TIFFmalloc(tif->tif_rawdatasize=4096); /* Imp: check */
 tif->tif_rawcp=tif->tif_rawdata;
 tif->tif_rawcc=0;
 if (TIFFInitLZW(tif) &&
     LZWSetupEncode(tif) &&
     LZWPreEncode(tif) /* for each strip */) {
   return 1;
 }
 LZWCleanup(tif);
 _TIFFfree(tif->tif_rawdata);
 return 0;
}


#if 0
/**** pts ****/
int main(int argc, char **argv) {
 filter_t filter;
 FILE *sin, *sout;
 inname="STDIN";

 if (argc>=2 && argc<=4 && argv[1][0]=='e') {
   filter=lzw_encode;
 } else if (argc>=2 && argc<=4 && argv[1][0]=='d') {
   filter=lzw_decode;
 } else {
   fprintf(stderr,
     "This is PotterSoftware LZW codec v0.1, (C) [email protected] in Late Dec 2001\n"
     "THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK!\n"
     "This program is free software, covered by the GNU GPL.\n"
     "  Derived from code Copyright (c) 1988-1997 Sam Leffler\n"
     "  Derived from code Copyright (c) 1991-1997 Silicon Graphics, Inc.\n\n"
     "Usage: %s encode|decode [INFILE] [OUTFILE]\n\n"
     "Unspecified file names mean STDIN or STDOUT.\n"
     "Encoding is /LZWEncode compression, decoding is /LZWDecode uncompression.\n\n"
     "Note that the LZW compression (but not uncompression) is patented by\n"
     "Unisys (patent number #4,558,302), so use this program at your own legal\n"
     "risk!\n"
     ,argv[0]);
   return 2;
 }
 if (argc>=3) sin= fopen(inname=argv[2],"rb");
         else sin= fdopen(0, "rb");
 if (sin==0) {
   fprintf(stderr, "%s: error opening infile\n", argv[0]);
   return 3;
 }
 if (argc>=4) sout=fopen(inname=argv[3],"wb");
         else sout=fdopen(1, "wb");
 if (sout==0) {
   fprintf(stderr, "%s: error opening outfile\n", argv[0]);
   return 4;
 }
 return !filter(sin, sout);
 /* fclose(sout); fclose(sin); */
}
#endif