/************************************************************************/
/*									*/
/*  Simple io streams, encoding/decoding into/from 12 bits LZW format.	*/
/*									*/
/*  NOTE that the initial 'CodeSize' byte of the LZW stream is NOT	*/
/*  read nor written by this library. It is passed as an argument to	*/
/*  the stream open routines. This allows us to ignore the fact that	*/
/*  files have the compressed data in a special format. The indirection	*/
/*  GIF stream takes care of that.					*/
/*									*/
/*  This is an isolated and optimized version of code found in 'giflib'	*/
/*  The Original Authors:						*/
/*									*/
/*  14 Jun 89 - Version 1.0 by Gershon Elber.				*/
/*   3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89,	*/
/*		Unique names).						*/
/*  26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)	*/
/*									*/
/*  Also includes fragments borrowed from the ImageMagick code.		*/
/*									*/
/************************************************************************/

#   include	"appUtilConfig.h"

#   include	<stdlib.h>
#   include	<string.h>

#   include	"sioLzw.h"
#   include	<appDebugon.h>

/************************************************************************/
/*									*/
/*  Common LZW Compression/Decompression state variables.		*/
/*									*/
/************************************************************************/

#   define LZ_MAX_CODE		4095	/* Biggest code possible in 12 bits. */
#   define LZ_BITS		12
#   define FIRST_CODE		4097    /* Impossible code, to signal first. */
#   define NO_SUCH_CODE		4098    /* Impossible code, to signal empty. */

typedef struct LzwState
    {
    int			lsCurrentCode;
			/************************************************/
			/*  The code last issued, or a bogus value to	*/
			/*  indicate that we are at the beginning of	*/
			/*  the output.					*/
			/************************************************/
    int			lsNextCode;
			/************************************************/
			/*  The next code the algorithm can generate.	*/
			/************************************************/
    int			lsCurrentCodeSize;
			/************************************************/
			/*  The number of bits required to represent	*/
			/*  RunningCode.				*/
			/************************************************/
    int			lsMaxCode1;
			/************************************************/
			/*  1 bigger than max. possible code, in	*/
			/*  RunningBits bits.				*/
			/************************************************/
    int			lsInitialCodeSize;
			/************************************************/
			/*  The number of bits needed to hold all	*/
			/*  symbold in the original alphabet.		*/
			/************************************************/
    int			lsClearCode;
    int			lsEOFCode;
			/************************************************/
			/*  Special Codes.				*/
			/************************************************/
    int			lsBitsAccumulated;
    unsigned long	lsAccumulator;
			/************************************************/
			/*  For collecting codes in bytes.		*/
			/*  -   Number of bits in CrntShiftDWord	*/
			/*  -   To hold the byte values.		*/
			/************************************************/
    } LzwState;

/************************************************************************/
/*									*/
/*  Initialise the state of a compressor/decompressor.			*/
/*									*/
/************************************************************************/

static void sioLzwInitState(	LzwState *	ls,
				int		codeSize )
    {
    ls->lsInitialCodeSize= codeSize;
    ls->lsClearCode= ( 1 << codeSize );
    ls->lsEOFCode= ls->lsClearCode+ 1;
    ls->lsNextCode= ls->lsEOFCode+ 1;
    ls->lsCurrentCodeSize= codeSize + 1;
    ls->lsMaxCode1= 1 << ls->lsCurrentCodeSize;
    ls->lsBitsAccumulated= 0;
    ls->lsAccumulator= 0;

    ls->lsCurrentCode= FIRST_CODE;

    return;
    }

/************************************************************************/
/*									*/
/*  12 bits LZW decompression specific data.				*/
/*									*/
/************************************************************************/

typedef struct LzwInputStream
    {
    LzwState		lisState;
    SimpleInputStream *	lisSisLzw;

    int			lisExhausted;
    int			lisLastCode;
			/************************************************/
			/*  The code before the current code.		*/
			/************************************************/
    int			lisStackPtr;
			/************************************************/
			/*  For character stack (see below).		*/
			/************************************************/
    unsigned char	lisStack[LZ_MAX_CODE];
			/************************************************/
			/*  Decoded pixels are stacked here.		*/
			/************************************************/
    unsigned char	lisSuffix[LZ_MAX_CODE+1];
    unsigned int	lisPrefix[LZ_MAX_CODE+1];
			/************************************************/
			/*  Keep track of the meaning of the Codes.	*/
			/************************************************/
    } LzwInputStream;


/************************************************************************/
/*									*/
/*  Decompress a 12 bits LZW input stream.				*/
/*									*/
/************************************************************************/

/************************************************************************/
/*									*/
/*  The LZ decompression input routine:					*/
/*									*/
/*  This routine is responsable for the decompression of the bit	*/
/*  stream from 8 bits (bytes) packets, into the real codes.		*/
/*  Returns 0 if read succesfully, -1 otherwise.			*/
/*									*/
/*  1)  As long as we need to get more bytes from input stream for	*/
/*	next code							*/
/*  2)  Extract the code.						*/
/*  3)  And shift it away.						*/
/*  4)  Increment the next code to be implicitly expected. (What the	*/
/*	encoder is supposed to send next) and if it is beyond what fits	*/
/*	in the current number of bits increment the number of bits.	*/
/*	NOTE however that codes above 4095 are used for special		*/
/*	signaling.							*/
/*									*/
/************************************************************************/

static int sioInLzwReadCode(	LzwInputStream *	lis,
				int *			pCode )

{
    LzwState *			ls= &(lis->lisState);

    static unsigned int CodeMasks[]=
	{
	0x0000,
	0x0001,
	0x0003,
	0x0007,
	0x000f,
	0x001f,
	0x003f,
	0x007f,
	0x00ff,
	0x01ff,
	0x03ff,
	0x07ff,
	0x0fff
	};

    /*  1  */
    while( ls->lsBitsAccumulated < ls->lsCurrentCodeSize )
	{
	int			byte;

	byte= sioInGetByte( lis->lisSisLzw );
	if  ( byte == EOF )
	    { XDEB(byte); return -1; }

	ls->lsAccumulator |= ((unsigned long) byte) << ls->lsBitsAccumulated;
	ls->lsBitsAccumulated += 8;
	}

    /*  2  */
    *pCode = ls->lsAccumulator & CodeMasks[ls->lsCurrentCodeSize];

    /*  3  */
    ls->lsAccumulator >>= ls->lsCurrentCodeSize;
    ls->lsBitsAccumulated -=  ls->lsCurrentCodeSize;

    /*  4  */
    if  ( ++ls->lsNextCode > ls->lsMaxCode1	&&
	  ls->lsCurrentCodeSize < LZ_BITS		)
	{
	ls->lsMaxCode1 <<= 1;
	ls->lsCurrentCodeSize++;
	}

    return 0;
}

/************************************************************************/
/*									*/
/*  Routine to trace the Prefixes linked list until we get a prefix	*/
/*  which is not a code, but a pixel value (less than ClearCode).	*/
/*  Returns that pixel value.						*/
/*  If the image is defective, we might loop here forever, so we limit	*/
/*  the loops to the maximum possible when the image is image Ok:	*/
/*  LZ_MAX_CODE times.							*/
/*									*/
/************************************************************************/

static int sioInLzwGetPrefixChar(	const unsigned int *	Prefix,
					int			Code,
					int			ClearCode )
{
    int i = 0;

    while( Code > ClearCode	&&
	   i++ <= LZ_MAX_CODE	)
	{ Code = Prefix[Code];	}

    return Code;
}

/************************************************************************/
/*									*/
/*  The LZ decompression routine:					*/
/*									*/
/*  This version decompress the given gif file into Line of length	*/
/*  LineLen.								*/
/*  This routine can be called few times (one per scan line, for	*/
/*  example), in order to complete the whole image.			*/
/*									*/
/*  1)  To not try to continue after the end of input has been found	*/
/*	nor after a previous error.					*/
/*  2)  Pop the contents of the stack before reading the input stream.	*/
/*  3)  Until a sufficient number of bytes is returned, read codes from	*/
/*	the input stream and process them.				*/
/*									*/
/************************************************************************/

static int sioInLzwReadBytes(	void *		voidlis,
				unsigned char *	buffer,
				unsigned int	count )
{
    int				i = 0;
    int				j;
    int				CrntCode;
    int				EOFCode;
    int				ClearCode;
    int				CrntPrefix;
    int				LastCode;
    int				StackPtr;
    unsigned char *		Stack;
    unsigned char *		Suffix;
    unsigned int *		Prefix;

    LzwInputStream *		lis= (LzwInputStream *)voidlis;
    LzwState *			ls= &(lis->lisState);

    StackPtr= lis->lisStackPtr;
    Prefix = lis->lisPrefix;
    Suffix = lis->lisSuffix;
    Stack = lis->lisStack;
    EOFCode = ls->lsEOFCode;
    ClearCode = ls->lsClearCode;
    LastCode= lis->lisLastCode;

    /*  1  */
    if  ( lis->lisExhausted )
	{ LDEB(lis->lisExhausted); return 0; }

    /*  2  */
    while( StackPtr > 0 && i < count )
	{ buffer[i++]= Stack[--StackPtr];	}

    /*  3  */
    while( i < count )
	{
	if  ( sioInLzwReadCode( lis, &CrntCode ) )
    	    { LDEB(1); return -1;	}

	if  ( CrntCode == EOFCode )
	    { lis->lisExhausted= 1; i++; break; }
	else if (CrntCode == ClearCode) {
	    /* We need to start over again: */
	    for (j = 0; j <= LZ_MAX_CODE; j++) Prefix[j] = NO_SUCH_CODE;
	    ls->lsNextCode = ls->lsEOFCode + 1;
	    ls->lsCurrentCodeSize = ls->lsInitialCodeSize + 1;
	    ls->lsMaxCode1 = 1 << ls->lsCurrentCodeSize;
	    LastCode= lis->lisLastCode= NO_SUCH_CODE;
	}
	else {
	    /* Its regular code - if in pixel range simply add it to output  */
	    /* stream, otherwise trace to codes linked list until the prefix */
	    /* is in pixel range:					     */
	    if (CrntCode < ClearCode) {
		/* This is simple - its pixel scalar, so add it to output:   */
		buffer[i++] = CrntCode;
	    }
	    else {
		/* Its a code to needed to be traced: trace the linked list  */
		/* until the prefix is a pixel, while pushing the suffix     */
		/* pixels on our stack. If we done, pop the stack in reverse */
		/* (thats what stack is good for!) order to output.	     */
		if (Prefix[CrntCode] == NO_SUCH_CODE) {
		    /* Only allowed if CrntCode is exactly the running code: */
		    /* In that case CrntCode = XXXCode, CrntCode or the	     */
		    /* prefix code is last code and the suffix char is	     */
		    /* exactly the prefix of last code!			     */
		    if (CrntCode == ls->lsNextCode - 2) {
			CrntPrefix = LastCode;
			Suffix[ls->lsNextCode - 2] =
			Stack[StackPtr++] = sioInLzwGetPrefixChar(Prefix,
							LastCode, ClearCode);
		    }
		    else {
			LDEB(1); return -1;
		    }
		}
		else
		    CrntPrefix = CrntCode;

		/* Now (if image is O.K.) we should not get an NO_SUCH_CODE  */
		/* During the trace. As we might loop forever, in case of    */
		/* defective image, we count the number of loops we trace    */
		/* and stop if we got LZ_MAX_CODE. obviously we can not      */
		/* loop more than that.					     */
		j = 0;
		while (j++ <= LZ_MAX_CODE &&
		       CrntPrefix > ClearCode &&
		       CrntPrefix <= LZ_MAX_CODE) {
		    Stack[StackPtr++] = Suffix[CrntPrefix];
		    CrntPrefix = Prefix[CrntPrefix];
		}
		if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
		    LLLDEB(j,CrntPrefix,LZ_MAX_CODE);
		    return -1;
		}
		/* Push the last character on stack: */
		Stack[StackPtr++] = CrntPrefix;

		/* Now lets pop all the stack into output: */
		while (StackPtr != 0 && i < count)
		    buffer[i++] = Stack[--StackPtr];
	    }
	    if (LastCode != NO_SUCH_CODE) {
		Prefix[ls->lsNextCode - 2] = LastCode;

		if (CrntCode == ls->lsNextCode - 2) {
		    /* Only allowed if CrntCode is exactly the running code: */
		    /* In that case CrntCode = XXXCode, CrntCode or the	     */
		    /* prefix code is last code and the suffix char is	     */
		    /* exactly the prefix of last code!			     */
		    Suffix[ls->lsNextCode - 2] =
			sioInLzwGetPrefixChar(Prefix, LastCode, ClearCode);
		}
		else {
		    Suffix[ls->lsNextCode - 2] =
			sioInLzwGetPrefixChar(Prefix, CrntCode, ClearCode);
		}
	    }
	    LastCode = CrntCode;
	}
    }

    lis->lisLastCode= LastCode;
    lis->lisStackPtr= StackPtr;

    return i;
}


/************************************************************************/
/*									*/
/*  Close an Lzw Input stream.						*/
/*									*/
/*  1)  First drain it.							*/
/*									*/
/************************************************************************/

static int sioInLzwClose(	void *	voidlis )
    {
    int				rval= 0;
    LzwInputStream *		lis= (LzwInputStream *)voidlis;

    /*  1 */
    while( ! lis->lisExhausted )
	{
	unsigned char	buffer[SIOsizBUF];

	if  ( sioInLzwReadBytes( voidlis, buffer, SIOsizBUF ) < 0 )
	    { LDEB(1); rval= -1; break;	}
	}

    free( voidlis );

    return rval;
    }

SimpleInputStream * sioInLzwGifOpen(	SimpleInputStream *	sisLzw,
					int			codeSize )
    {
    SimpleInputStream *		sis;
    LzwInputStream *		lis;

    int				i;
    unsigned int *		p;

    lis= (LzwInputStream *)malloc( sizeof(LzwInputStream) );
    if  ( ! lis )
	{ XDEB(lis); return (SimpleInputStream *)0;	}

    lis->lisSisLzw= sisLzw;
    lis->lisExhausted= 0;

    lis->lisStackPtr= 0;
    lis->lisLastCode= NO_SUCH_CODE;

    sioLzwInitState( &(lis->lisState), codeSize );

    p= lis->lisPrefix;
    for ( i = 0; i <= LZ_MAX_CODE; p++, i++ )
	{ *p= NO_SUCH_CODE;	}

    sis= sioInOpen( (void *)lis, sioInLzwReadBytes, sioInLzwClose );

    if  ( ! sis )
	{ XDEB(sis); free( lis ); return (SimpleInputStream *)0; }

    return sis;
    }

/************************************************************************/
/*									*/
/*  SimpleOutputStreams doing LZW compression.				*/
/*									*/
/*  1)  Mask nonsense bits from the input of the compressor.		*/
/*									*/
/************************************************************************/

static const unsigned char SIO_LZW_OutMasks[]=
    {
    0x00,
    0x01,
    0x03,
    0x07,
    0x0f,
    0x1f,
    0x3f,
    0x7f,
    0xff
    };

#define HT_SIZE			8192	   /* 12bits = 4096 or twice as big! */
#define HT_KEY_MASK		0x1FFF			      /* 13bits keys */
#define HT_KEY_NUM_BITS		13			      /* 13bits keys */
#define HT_MAX_KEY		8191	/* 13bits - 1, maximal code possible */
#define HT_MAX_CODE		4095	/* Biggest code possible in 12 bits. */

/* The 32 bits of the long are divided into two parts for the key & code:   */
/* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
/* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits.	    */
#define HT_GET_KEY(l)	(l >> 12)
#define HT_GET_CODE(l)	(l & 0x0FFF)
#define HT_PUT_KEY(l)	(l << 12)
#define HT_PUT_CODE(l)	(l & 0x0FFF)

typedef struct GifHashTableType {
    unsigned long HTable[HT_SIZE];
} GifHashTableType;

/******************************************************************************
* Routine to generate an HKey for the hashtable out of the given unique key.  *
* The given Key is assumed to be 20 bits as follows: lower 8 bits are the     *
* new postfix character, while the upper 12 bits are the prefix code.	      *
* Because the average hit ratio is only 2 (2 hash references per entry),      *
* evaluating more complex keys (such as twin prime keys) is not worth it!     *
******************************************************************************/

# define KeyItem(Item) \
    ((((unsigned long)(Item) >> 12) ^ (unsigned long)(Item)) & HT_KEY_MASK)

/******************************************************************************
* Routine to clear the HashTable to an empty state.			      *
* This part is a little machine depended. Use the commented part otherwise.   *
******************************************************************************/

static void _ClearHashTable(GifHashTableType *HashTable)
{
    memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(long));
}

/******************************************************************************
* Routine to insert a new Item into the HashTable. The data is assumed to be  *
* new one.								      *
******************************************************************************/

static void _InsertHashTable(GifHashTableType *HashTable, unsigned long Key, int Code)
{
    int HKey = KeyItem(Key);
    unsigned long *HTable = HashTable -> HTable;

    while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
	HKey = (HKey + 1) & HT_KEY_MASK;
    }
    HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
}

/******************************************************************************
* Routine to test if given Key exists in HashTable and if so returns its code *
* Returns the Code if key was found, -1 if not.				      *
******************************************************************************/

static int _ExistsHashTable(	GifHashTableType *	HashTable,
				unsigned long		Key )
{
    int			HKey= KeyItem(Key);
    unsigned long *	HTable= HashTable -> HTable, HTKey;

    while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
	if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
	HKey = (HKey + 1) & HT_KEY_MASK;
    }

    return -1;
}

/************************************************************************/
/*									*/
/*  Actual Output stream object.					*/
/*									*/
/************************************************************************/

typedef struct LzwGifOutputStream
    {
    GifHashTableType		losHashTable;
    LzwState			losState;
    SimpleOutputStream *	losSosLzw;
    } LzwGifOutputStream;

/************************************************************************/
/*									*/
/*  The actual output routine to the (blocked) stream: 			*/
/*  This routine is responsible for the translation of the bit stream	*/
/*  into 8 bits (byte) packets.						*/
/*									*/
/*  1)  Emit full bytes.						*/
/*									*/
/************************************************************************/

static int sioOutLzwGifWriteCode(	LzwGifOutputStream *	los,
					int			code )
    {
    LzwState *			ls= &(los->losState);
    int				rval= 0;

    ls->lsAccumulator |= ( (long)code ) << ls->lsBitsAccumulated;
    ls->lsBitsAccumulated += ls->lsCurrentCodeSize;

    while( ls->lsBitsAccumulated >= 8 )
	{
	/*  1  */
	if  ( sioOutPutByte( ls->lsAccumulator & 0xff,
						    los->losSosLzw ) == EOF )
	    { rval= -1;	}

	ls->lsAccumulator >>= 8;
	ls->lsBitsAccumulated -= 8;
	}

    return rval;
    }

/************************************************************************/
/*									*/
/*  Close an LZW output stream.						*/
/*									*/
/*  1)  As the encoding process is one code behind, issue the last	*/
/*	code.								*/
/*  2)  Issue the EOF code.						*/
/*  3)  Emit all bits that are heaped up in the encoder.		*/
/*  4)  Free memory.							*/
/*									*/
/************************************************************************/

static int sioOutLzwGifClose(	void *		voidlos )
    {
    int				rval= 0;
    LzwGifOutputStream *	los= (LzwGifOutputStream *)voidlos;
    LzwState *			ls= &(los->losState);

    /*  1  */
    if  ( sioOutLzwGifWriteCode( los, ls->lsCurrentCode ) )
	{ XDEB(ls->lsCurrentCode); rval= -1;	}

    /*  2  */
    if  ( sioOutLzwGifWriteCode( los, ls->lsEOFCode ) )
	{ XDEB(ls->lsEOFCode); rval= -1;	}

    /*  3  */
    while( ls->lsBitsAccumulated > 0 )
	{
	if  ( sioOutPutByte( ls->lsAccumulator & 0xff,
						    los->losSosLzw ) == EOF )
	    { LDEB(1); rval= -1;	}

	ls->lsAccumulator >>= 8;
	ls->lsBitsAccumulated -=  8;
	}

    /*  4  */
    free( los );

    return rval;
    }

/************************************************************************/
/*									*/
/*  The LZ compression routine:						*/
/*  This version compress the given buffer of length count.		*/
/*  This routine can be called several times (one per scan line, for	*/
/*  example), in order to compress the whole image			*/
/*									*/
/*  1)  If the Current code is the initial value that serves to		*/
/*	flag this, set the current code to the first character to	*/
/*	compress. (and consume it)					*/
/*  2)  Make a new key to search the hash table.			*/
/*  3)  Lookup in hash table.						*/
/*  4)  If it is there, simply take the new code as the current code.	*/
/*  5)  If not, emit the current code and set the current code to the	*/
/*	pixel value.							*/
/*      If next code cannot fit into the current code size, must raise	*/
/*	the code size.							*/
/*  6)  BUT.. If the hash table is full, send a Clear code and clear	*/
/*	the hash table as well.						*/
/*									*/
/************************************************************************/

static int sioOutLzwGifWriteBytes(
				void *			voidlos,
				const unsigned char *	buffer,
				int			count )
{
    LzwGifOutputStream *	los= (LzwGifOutputStream *)voidlos;
    LzwState *			ls= &(los->losState);

    int				i= 0;

    /*  1  */
    if  ( ls->lsCurrentCode == FIRST_CODE )
	{
	ls->lsCurrentCode=
		    buffer[i++] & SIO_LZW_OutMasks[ls->lsInitialCodeSize];
	}

    while( i < count )
	{
	int	val= buffer[i++] & SIO_LZW_OutMasks[ls->lsInitialCodeSize];
	int	nextKey;
	int	nextCode;

	/*  2  */
	nextKey= ( ((unsigned long) ls->lsCurrentCode ) << 8) + val;

	/*  3  */
	nextCode= _ExistsHashTable( &(los->losHashTable), nextKey );

	/*  4  */
	if  ( nextCode >= 0 )
	    { ls->lsCurrentCode= nextCode;	}
	else{
	    /*  5  */
	    if  ( sioOutLzwGifWriteCode( los, ls->lsCurrentCode ) )
		{ LDEB(ls->lsCurrentCode); return -1;	}

	    ls->lsCurrentCode= val;

	    if  ( ls->lsNextCode >= ls->lsMaxCode1 )
		{ ls->lsMaxCode1= 1 << ++(ls->lsCurrentCodeSize);	}

	    /*  6  */
	    if  ( ls->lsCurrentCodeSize > 12 )
		{
		ls->lsCurrentCodeSize= 12;

		if  ( sioOutLzwGifWriteCode( los, ls->lsClearCode ) )
		    { LDEB(ls->lsCurrentCode); return -1;	}

		ls->lsNextCode= ls->lsEOFCode+ 1;
		ls->lsCurrentCodeSize= ls->lsInitialCodeSize+ 1;
		ls->lsMaxCode1= 1 << ls->lsCurrentCodeSize;

		_ClearHashTable( &(los->losHashTable) );
		}
	    else{
		_InsertHashTable( &(los->losHashTable),
					    nextKey, ls->lsNextCode );
		ls->lsNextCode++;
		}
	   }
	}

    return count;
}

/************************************************************************/
/*									*/
/*  Open a 12 bit LZW output stream.					*/
/*									*/
/*  NOTE that the initial code size has been communicated outside the	*/
/*	compressed stream. In the GIF case even before the packeted	*/
/*	stream packet header of the first packet.			*/
/*									*/
/*  1)  Allocate memory and remember the output stream.			*/
/*  2)  Initialize the hash table by clearing it.			*/
/*  3)  Initialize the general LZW administration for the current code	*/
/*	size.								*/
/*  4)  General SioOut administration.					*/
/*  Z)  Start with a clear code to be sure that the decoder has also	*/
/*	cleared its hash table.						*/
/*									*/
/************************************************************************/

SimpleOutputStream * sioOutLzwGifOpen(	SimpleOutputStream *	sosLzw,
					int			codeSize )
    {
    SimpleOutputStream *	sos;
    LzwGifOutputStream *	los;

    /*  1  */
    los= (LzwGifOutputStream *)malloc( sizeof(LzwGifOutputStream) );
    if  ( ! los )
	{ XDEB(los); return (SimpleOutputStream *)0;	}

    los->losSosLzw= sosLzw;

    /*  2  */
    _ClearHashTable( &(los->losHashTable) );

    /*  3  */
    sioLzwInitState( &(los->losState), codeSize );

    /*  4  */
    sos= sioOutOpen( (void *)los, sioOutLzwGifWriteBytes, sioOutLzwGifClose );

    if  ( ! sos )
	{ XDEB(sos); free( los ); return (SimpleOutputStream *)0; }

    /*  Z  */
    if  ( sioOutLzwGifWriteCode( los, los->losState.lsClearCode ) )
	{ LDEB(1); sioOutClose( sos ); return (SimpleOutputStream *)0; }

    return sos;
    }

