1 /************************************************************************/
2 /*									*/
3 /*  Simple io streams, encoding/decoding into/from 12 bits LZW format.	*/
4 /*									*/
5 /*  NOTE that the initial 'CodeSize' byte of the LZW stream is NOT	*/
6 /*  read nor written by this library. It is passed as an argument to	*/
7 /*  the stream open routines. This allows us to ignore the fact that	*/
8 /*  files have the compressed data in a special format. The indirection	*/
9 /*  GIF stream takes care of that.					*/
10 /*									*/
11 /*  This is an isolated and optimized version of code found in 'giflib'	*/
12 /*  The Original Authors:						*/
13 /*									*/
14 /*  14 Jun 89 - Version 1.0 by Gershon Elber.				*/
15 /*   3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89,	*/
16 /*		Unique names).						*/
17 /*  26 Jun 96 - Version 3.0 by Eric S. Raymond (Full GIF89 support)	*/
18 /*									*/
19 /*  Also includes fragments borrowed from the ImageMagick code.		*/
20 /*									*/
21 /************************************************************************/
22 
23 #   include	"appUtilConfig.h"
24 
25 #   include	<stdlib.h>
26 #   include	<string.h>
27 
28 #   include	"sioLzw.h"
29 #   include	<appDebugon.h>
30 
31 /************************************************************************/
32 /*									*/
33 /*  Common LZW Compression/Decompression state variables.		*/
34 /*									*/
35 /************************************************************************/
36 
37 #   define LZ_MAX_CODE		4095	/* Biggest code possible in 12 bits. */
38 #   define LZ_BITS		12
39 #   define FIRST_CODE		4097    /* Impossible code, to signal first. */
40 #   define NO_SUCH_CODE		4098    /* Impossible code, to signal empty. */
41 
42 typedef struct LzwState
43     {
44     int			lsCurrentCode;
45 			/************************************************/
46 			/*  The code last issued, or a bogus value to	*/
47 			/*  indicate that we are at the beginning of	*/
48 			/*  the output.					*/
49 			/************************************************/
50     int			lsNextCode;
51 			/************************************************/
52 			/*  The next code the algorithm can generate.	*/
53 			/************************************************/
54     int			lsCurrentCodeSize;
55 			/************************************************/
56 			/*  The number of bits required to represent	*/
57 			/*  RunningCode.				*/
58 			/************************************************/
59     int			lsMaxCode1;
60 			/************************************************/
61 			/*  1 bigger than max. possible code, in	*/
62 			/*  RunningBits bits.				*/
63 			/************************************************/
64     int			lsInitialCodeSize;
65 			/************************************************/
66 			/*  The number of bits needed to hold all	*/
67 			/*  symbold in the original alphabet.		*/
68 			/************************************************/
69     int			lsClearCode;
70     int			lsEOFCode;
71 			/************************************************/
72 			/*  Special Codes.				*/
73 			/************************************************/
74     int			lsBitsAccumulated;
75     unsigned long	lsAccumulator;
76 			/************************************************/
77 			/*  For collecting codes in bytes.		*/
78 			/*  -   Number of bits in CrntShiftDWord	*/
79 			/*  -   To hold the byte values.		*/
80 			/************************************************/
81     } LzwState;
82 
83 /************************************************************************/
84 /*									*/
85 /*  Initialise the state of a compressor/decompressor.			*/
86 /*									*/
87 /************************************************************************/
88 
sioLzwInitState(LzwState * ls,int codeSize)89 static void sioLzwInitState(	LzwState *	ls,
90 				int		codeSize )
91     {
92     ls->lsInitialCodeSize= codeSize;
93     ls->lsClearCode= ( 1 << codeSize );
94     ls->lsEOFCode= ls->lsClearCode+ 1;
95     ls->lsNextCode= ls->lsEOFCode+ 1;
96     ls->lsCurrentCodeSize= codeSize + 1;
97     ls->lsMaxCode1= 1 << ls->lsCurrentCodeSize;
98     ls->lsBitsAccumulated= 0;
99     ls->lsAccumulator= 0;
100 
101     ls->lsCurrentCode= FIRST_CODE;
102 
103     return;
104     }
105 
106 /************************************************************************/
107 /*									*/
108 /*  12 bits LZW decompression specific data.				*/
109 /*									*/
110 /************************************************************************/
111 
112 typedef struct LzwInputStream
113     {
114     LzwState		lisState;
115     SimpleInputStream *	lisSisLzw;
116 
117     int			lisExhausted;
118     int			lisLastCode;
119 			/************************************************/
120 			/*  The code before the current code.		*/
121 			/************************************************/
122     int			lisStackPtr;
123 			/************************************************/
124 			/*  For character stack (see below).		*/
125 			/************************************************/
126     unsigned char	lisStack[LZ_MAX_CODE];
127 			/************************************************/
128 			/*  Decoded pixels are stacked here.		*/
129 			/************************************************/
130     unsigned char	lisSuffix[LZ_MAX_CODE+1];
131     unsigned int	lisPrefix[LZ_MAX_CODE+1];
132 			/************************************************/
133 			/*  Keep track of the meaning of the Codes.	*/
134 			/************************************************/
135     } LzwInputStream;
136 
137 
138 /************************************************************************/
139 /*									*/
140 /*  Decompress a 12 bits LZW input stream.				*/
141 /*									*/
142 /************************************************************************/
143 
144 /************************************************************************/
145 /*									*/
146 /*  The LZ decompression input routine:					*/
147 /*									*/
148 /*  This routine is responsable for the decompression of the bit	*/
149 /*  stream from 8 bits (bytes) packets, into the real codes.		*/
150 /*  Returns 0 if read succesfully, -1 otherwise.			*/
151 /*									*/
152 /*  1)  As long as we need to get more bytes from input stream for	*/
153 /*	next code							*/
154 /*  2)  Extract the code.						*/
155 /*  3)  And shift it away.						*/
156 /*  4)  Increment the next code to be implicitly expected. (What the	*/
157 /*	encoder is supposed to send next) and if it is beyond what fits	*/
158 /*	in the current number of bits increment the number of bits.	*/
159 /*	NOTE however that codes above 4095 are used for special		*/
160 /*	signaling.							*/
161 /*									*/
162 /************************************************************************/
163 
sioInLzwReadCode(LzwInputStream * lis,int * pCode)164 static int sioInLzwReadCode(	LzwInputStream *	lis,
165 				int *			pCode )
166 
167 {
168     LzwState *			ls= &(lis->lisState);
169 
170     static unsigned int CodeMasks[]=
171 	{
172 	0x0000,
173 	0x0001,
174 	0x0003,
175 	0x0007,
176 	0x000f,
177 	0x001f,
178 	0x003f,
179 	0x007f,
180 	0x00ff,
181 	0x01ff,
182 	0x03ff,
183 	0x07ff,
184 	0x0fff
185 	};
186 
187     /*  1  */
188     while( ls->lsBitsAccumulated < ls->lsCurrentCodeSize )
189 	{
190 	int			byte;
191 
192 	byte= sioInGetByte( lis->lisSisLzw );
193 	if  ( byte == EOF )
194 	    { XDEB(byte); return -1; }
195 
196 	ls->lsAccumulator |= ((unsigned long) byte) << ls->lsBitsAccumulated;
197 	ls->lsBitsAccumulated += 8;
198 	}
199 
200     /*  2  */
201     *pCode = ls->lsAccumulator & CodeMasks[ls->lsCurrentCodeSize];
202 
203     /*  3  */
204     ls->lsAccumulator >>= ls->lsCurrentCodeSize;
205     ls->lsBitsAccumulated -=  ls->lsCurrentCodeSize;
206 
207     /*  4  */
208     if  ( ++ls->lsNextCode > ls->lsMaxCode1	&&
209 	  ls->lsCurrentCodeSize < LZ_BITS		)
210 	{
211 	ls->lsMaxCode1 <<= 1;
212 	ls->lsCurrentCodeSize++;
213 	}
214 
215     return 0;
216 }
217 
218 /************************************************************************/
219 /*									*/
220 /*  Routine to trace the Prefixes linked list until we get a prefix	*/
221 /*  which is not a code, but a pixel value (less than ClearCode).	*/
222 /*  Returns that pixel value.						*/
223 /*  If the image is defective, we might loop here forever, so we limit	*/
224 /*  the loops to the maximum possible when the image is image Ok:	*/
225 /*  LZ_MAX_CODE times.							*/
226 /*									*/
227 /************************************************************************/
228 
sioInLzwGetPrefixChar(const unsigned int * Prefix,int Code,int ClearCode)229 static int sioInLzwGetPrefixChar(	const unsigned int *	Prefix,
230 					int			Code,
231 					int			ClearCode )
232 {
233     int i = 0;
234 
235     while( Code > ClearCode	&&
236 	   i++ <= LZ_MAX_CODE	)
237 	{ Code = Prefix[Code];	}
238 
239     return Code;
240 }
241 
242 /************************************************************************/
243 /*									*/
244 /*  The LZ decompression routine:					*/
245 /*									*/
246 /*  This version decompress the given gif file into Line of length	*/
247 /*  LineLen.								*/
248 /*  This routine can be called few times (one per scan line, for	*/
249 /*  example), in order to complete the whole image.			*/
250 /*									*/
251 /*  1)  To not try to continue after the end of input has been found	*/
252 /*	nor after a previous error.					*/
253 /*  2)  Pop the contents of the stack before reading the input stream.	*/
254 /*  3)  Until a sufficient number of bytes is returned, read codes from	*/
255 /*	the input stream and process them.				*/
256 /*									*/
257 /************************************************************************/
258 
sioInLzwReadBytes(void * voidlis,unsigned char * buffer,unsigned int count)259 static int sioInLzwReadBytes(	void *		voidlis,
260 				unsigned char *	buffer,
261 				unsigned int	count )
262 {
263     int				i = 0;
264     int				j;
265     int				CrntCode;
266     int				EOFCode;
267     int				ClearCode;
268     int				CrntPrefix;
269     int				LastCode;
270     int				StackPtr;
271     unsigned char *		Stack;
272     unsigned char *		Suffix;
273     unsigned int *		Prefix;
274 
275     LzwInputStream *		lis= (LzwInputStream *)voidlis;
276     LzwState *			ls= &(lis->lisState);
277 
278     StackPtr= lis->lisStackPtr;
279     Prefix = lis->lisPrefix;
280     Suffix = lis->lisSuffix;
281     Stack = lis->lisStack;
282     EOFCode = ls->lsEOFCode;
283     ClearCode = ls->lsClearCode;
284     LastCode= lis->lisLastCode;
285 
286     /*  1  */
287     if  ( lis->lisExhausted )
288 	{ LDEB(lis->lisExhausted); return 0; }
289 
290     /*  2  */
291     while( StackPtr > 0 && i < count )
292 	{ buffer[i++]= Stack[--StackPtr];	}
293 
294     /*  3  */
295     while( i < count )
296 	{
297 	if  ( sioInLzwReadCode( lis, &CrntCode ) )
298     	    { LDEB(1); return -1;	}
299 
300 	if  ( CrntCode == EOFCode )
301 	    { lis->lisExhausted= 1; i++; break; }
302 	else if (CrntCode == ClearCode) {
303 	    /* We need to start over again: */
304 	    for (j = 0; j <= LZ_MAX_CODE; j++) Prefix[j] = NO_SUCH_CODE;
305 	    ls->lsNextCode = ls->lsEOFCode + 1;
306 	    ls->lsCurrentCodeSize = ls->lsInitialCodeSize + 1;
307 	    ls->lsMaxCode1 = 1 << ls->lsCurrentCodeSize;
308 	    LastCode= lis->lisLastCode= NO_SUCH_CODE;
309 	}
310 	else {
311 	    /* Its regular code - if in pixel range simply add it to output  */
312 	    /* stream, otherwise trace to codes linked list until the prefix */
313 	    /* is in pixel range:					     */
314 	    if (CrntCode < ClearCode) {
315 		/* This is simple - its pixel scalar, so add it to output:   */
316 		buffer[i++] = CrntCode;
317 	    }
318 	    else {
319 		/* Its a code to needed to be traced: trace the linked list  */
320 		/* until the prefix is a pixel, while pushing the suffix     */
321 		/* pixels on our stack. If we done, pop the stack in reverse */
322 		/* (thats what stack is good for!) order to output.	     */
323 		if (Prefix[CrntCode] == NO_SUCH_CODE) {
324 		    /* Only allowed if CrntCode is exactly the running code: */
325 		    /* In that case CrntCode = XXXCode, CrntCode or the	     */
326 		    /* prefix code is last code and the suffix char is	     */
327 		    /* exactly the prefix of last code!			     */
328 		    if (CrntCode == ls->lsNextCode - 2) {
329 			CrntPrefix = LastCode;
330 			Suffix[ls->lsNextCode - 2] =
331 			Stack[StackPtr++] = sioInLzwGetPrefixChar(Prefix,
332 							LastCode, ClearCode);
333 		    }
334 		    else {
335 			LDEB(1); return -1;
336 		    }
337 		}
338 		else
339 		    CrntPrefix = CrntCode;
340 
341 		/* Now (if image is O.K.) we should not get an NO_SUCH_CODE  */
342 		/* During the trace. As we might loop forever, in case of    */
343 		/* defective image, we count the number of loops we trace    */
344 		/* and stop if we got LZ_MAX_CODE. obviously we can not      */
345 		/* loop more than that.					     */
346 		j = 0;
347 		while (j++ <= LZ_MAX_CODE &&
348 		       CrntPrefix > ClearCode &&
349 		       CrntPrefix <= LZ_MAX_CODE) {
350 		    Stack[StackPtr++] = Suffix[CrntPrefix];
351 		    CrntPrefix = Prefix[CrntPrefix];
352 		}
353 		if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
354 		    LLLDEB(j,CrntPrefix,LZ_MAX_CODE);
355 		    return -1;
356 		}
357 		/* Push the last character on stack: */
358 		Stack[StackPtr++] = CrntPrefix;
359 
360 		/* Now lets pop all the stack into output: */
361 		while (StackPtr != 0 && i < count)
362 		    buffer[i++] = Stack[--StackPtr];
363 	    }
364 	    if (LastCode != NO_SUCH_CODE) {
365 		Prefix[ls->lsNextCode - 2] = LastCode;
366 
367 		if (CrntCode == ls->lsNextCode - 2) {
368 		    /* Only allowed if CrntCode is exactly the running code: */
369 		    /* In that case CrntCode = XXXCode, CrntCode or the	     */
370 		    /* prefix code is last code and the suffix char is	     */
371 		    /* exactly the prefix of last code!			     */
372 		    Suffix[ls->lsNextCode - 2] =
373 			sioInLzwGetPrefixChar(Prefix, LastCode, ClearCode);
374 		}
375 		else {
376 		    Suffix[ls->lsNextCode - 2] =
377 			sioInLzwGetPrefixChar(Prefix, CrntCode, ClearCode);
378 		}
379 	    }
380 	    LastCode = CrntCode;
381 	}
382     }
383 
384     lis->lisLastCode= LastCode;
385     lis->lisStackPtr= StackPtr;
386 
387     return i;
388 }
389 
390 
391 /************************************************************************/
392 /*									*/
393 /*  Close an Lzw Input stream.						*/
394 /*									*/
395 /*  1)  First drain it.							*/
396 /*									*/
397 /************************************************************************/
398 
sioInLzwClose(void * voidlis)399 static int sioInLzwClose(	void *	voidlis )
400     {
401     int				rval= 0;
402     LzwInputStream *		lis= (LzwInputStream *)voidlis;
403 
404     /*  1 */
405     while( ! lis->lisExhausted )
406 	{
407 	unsigned char	buffer[SIOsizBUF];
408 
409 	if  ( sioInLzwReadBytes( voidlis, buffer, SIOsizBUF ) < 0 )
410 	    { LDEB(1); rval= -1; break;	}
411 	}
412 
413     free( voidlis );
414 
415     return rval;
416     }
417 
sioInLzwGifOpen(SimpleInputStream * sisLzw,int codeSize)418 SimpleInputStream * sioInLzwGifOpen(	SimpleInputStream *	sisLzw,
419 					int			codeSize )
420     {
421     SimpleInputStream *		sis;
422     LzwInputStream *		lis;
423 
424     int				i;
425     unsigned int *		p;
426 
427     lis= (LzwInputStream *)malloc( sizeof(LzwInputStream) );
428     if  ( ! lis )
429 	{ XDEB(lis); return (SimpleInputStream *)0;	}
430 
431     lis->lisSisLzw= sisLzw;
432     lis->lisExhausted= 0;
433 
434     lis->lisStackPtr= 0;
435     lis->lisLastCode= NO_SUCH_CODE;
436 
437     sioLzwInitState( &(lis->lisState), codeSize );
438 
439     p= lis->lisPrefix;
440     for ( i = 0; i <= LZ_MAX_CODE; p++, i++ )
441 	{ *p= NO_SUCH_CODE;	}
442 
443     sis= sioInOpen( (void *)lis, sioInLzwReadBytes, sioInLzwClose );
444 
445     if  ( ! sis )
446 	{ XDEB(sis); free( lis ); return (SimpleInputStream *)0; }
447 
448     return sis;
449     }
450 
451 /************************************************************************/
452 /*									*/
453 /*  SimpleOutputStreams doing LZW compression.				*/
454 /*									*/
455 /*  1)  Mask nonsense bits from the input of the compressor.		*/
456 /*									*/
457 /************************************************************************/
458 
459 static const unsigned char SIO_LZW_OutMasks[]=
460     {
461     0x00,
462     0x01,
463     0x03,
464     0x07,
465     0x0f,
466     0x1f,
467     0x3f,
468     0x7f,
469     0xff
470     };
471 
472 #define HT_SIZE			8192	   /* 12bits = 4096 or twice as big! */
473 #define HT_KEY_MASK		0x1FFF			      /* 13bits keys */
474 #define HT_KEY_NUM_BITS		13			      /* 13bits keys */
475 #define HT_MAX_KEY		8191	/* 13bits - 1, maximal code possible */
476 #define HT_MAX_CODE		4095	/* Biggest code possible in 12 bits. */
477 
478 /* The 32 bits of the long are divided into two parts for the key & code:   */
479 /* 1. The code is 12 bits as our compression algorithm is limited to 12bits */
480 /* 2. The key is 12 bits Prefix code + 8 bit new char or 20 bits.	    */
481 #define HT_GET_KEY(l)	(l >> 12)
482 #define HT_GET_CODE(l)	(l & 0x0FFF)
483 #define HT_PUT_KEY(l)	(l << 12)
484 #define HT_PUT_CODE(l)	(l & 0x0FFF)
485 
486 typedef struct GifHashTableType {
487     unsigned long HTable[HT_SIZE];
488 } GifHashTableType;
489 
490 /******************************************************************************
491 * Routine to generate an HKey for the hashtable out of the given unique key.  *
492 * The given Key is assumed to be 20 bits as follows: lower 8 bits are the     *
493 * new postfix character, while the upper 12 bits are the prefix code.	      *
494 * Because the average hit ratio is only 2 (2 hash references per entry),      *
495 * evaluating more complex keys (such as twin prime keys) is not worth it!     *
496 ******************************************************************************/
497 
498 # define KeyItem(Item) \
499     ((((unsigned long)(Item) >> 12) ^ (unsigned long)(Item)) & HT_KEY_MASK)
500 
501 /******************************************************************************
502 * Routine to clear the HashTable to an empty state.			      *
503 * This part is a little machine depended. Use the commented part otherwise.   *
504 ******************************************************************************/
505 
_ClearHashTable(GifHashTableType * HashTable)506 static void _ClearHashTable(GifHashTableType *HashTable)
507 {
508     memset(HashTable -> HTable, 0xFF, HT_SIZE * sizeof(long));
509 }
510 
511 /******************************************************************************
512 * Routine to insert a new Item into the HashTable. The data is assumed to be  *
513 * new one.								      *
514 ******************************************************************************/
515 
_InsertHashTable(GifHashTableType * HashTable,unsigned long Key,int Code)516 static void _InsertHashTable(GifHashTableType *HashTable, unsigned long Key, int Code)
517 {
518     int HKey = KeyItem(Key);
519     unsigned long *HTable = HashTable -> HTable;
520 
521     while (HT_GET_KEY(HTable[HKey]) != 0xFFFFFL) {
522 	HKey = (HKey + 1) & HT_KEY_MASK;
523     }
524     HTable[HKey] = HT_PUT_KEY(Key) | HT_PUT_CODE(Code);
525 }
526 
527 /******************************************************************************
528 * Routine to test if given Key exists in HashTable and if so returns its code *
529 * Returns the Code if key was found, -1 if not.				      *
530 ******************************************************************************/
531 
_ExistsHashTable(GifHashTableType * HashTable,unsigned long Key)532 static int _ExistsHashTable(	GifHashTableType *	HashTable,
533 				unsigned long		Key )
534 {
535     int			HKey= KeyItem(Key);
536     unsigned long *	HTable= HashTable -> HTable, HTKey;
537 
538     while ((HTKey = HT_GET_KEY(HTable[HKey])) != 0xFFFFFL) {
539 	if (Key == HTKey) return HT_GET_CODE(HTable[HKey]);
540 	HKey = (HKey + 1) & HT_KEY_MASK;
541     }
542 
543     return -1;
544 }
545 
546 /************************************************************************/
547 /*									*/
548 /*  Actual Output stream object.					*/
549 /*									*/
550 /************************************************************************/
551 
552 typedef struct LzwGifOutputStream
553     {
554     GifHashTableType		losHashTable;
555     LzwState			losState;
556     SimpleOutputStream *	losSosLzw;
557     } LzwGifOutputStream;
558 
559 /************************************************************************/
560 /*									*/
561 /*  The actual output routine to the (blocked) stream: 			*/
562 /*  This routine is responsible for the translation of the bit stream	*/
563 /*  into 8 bits (byte) packets.						*/
564 /*									*/
565 /*  1)  Emit full bytes.						*/
566 /*									*/
567 /************************************************************************/
568 
sioOutLzwGifWriteCode(LzwGifOutputStream * los,int code)569 static int sioOutLzwGifWriteCode(	LzwGifOutputStream *	los,
570 					int			code )
571     {
572     LzwState *			ls= &(los->losState);
573     int				rval= 0;
574 
575     ls->lsAccumulator |= ( (long)code ) << ls->lsBitsAccumulated;
576     ls->lsBitsAccumulated += ls->lsCurrentCodeSize;
577 
578     while( ls->lsBitsAccumulated >= 8 )
579 	{
580 	/*  1  */
581 	if  ( sioOutPutByte( ls->lsAccumulator & 0xff,
582 						    los->losSosLzw ) == EOF )
583 	    { rval= -1;	}
584 
585 	ls->lsAccumulator >>= 8;
586 	ls->lsBitsAccumulated -= 8;
587 	}
588 
589     return rval;
590     }
591 
592 /************************************************************************/
593 /*									*/
594 /*  Close an LZW output stream.						*/
595 /*									*/
596 /*  1)  As the encoding process is one code behind, issue the last	*/
597 /*	code.								*/
598 /*  2)  Issue the EOF code.						*/
599 /*  3)  Emit all bits that are heaped up in the encoder.		*/
600 /*  4)  Free memory.							*/
601 /*									*/
602 /************************************************************************/
603 
sioOutLzwGifClose(void * voidlos)604 static int sioOutLzwGifClose(	void *		voidlos )
605     {
606     int				rval= 0;
607     LzwGifOutputStream *	los= (LzwGifOutputStream *)voidlos;
608     LzwState *			ls= &(los->losState);
609 
610     /*  1  */
611     if  ( sioOutLzwGifWriteCode( los, ls->lsCurrentCode ) )
612 	{ XDEB(ls->lsCurrentCode); rval= -1;	}
613 
614     /*  2  */
615     if  ( sioOutLzwGifWriteCode( los, ls->lsEOFCode ) )
616 	{ XDEB(ls->lsEOFCode); rval= -1;	}
617 
618     /*  3  */
619     while( ls->lsBitsAccumulated > 0 )
620 	{
621 	if  ( sioOutPutByte( ls->lsAccumulator & 0xff,
622 						    los->losSosLzw ) == EOF )
623 	    { LDEB(1); rval= -1;	}
624 
625 	ls->lsAccumulator >>= 8;
626 	ls->lsBitsAccumulated -=  8;
627 	}
628 
629     /*  4  */
630     free( los );
631 
632     return rval;
633     }
634 
635 /************************************************************************/
636 /*									*/
637 /*  The LZ compression routine:						*/
638 /*  This version compress the given buffer of length count.		*/
639 /*  This routine can be called several times (one per scan line, for	*/
640 /*  example), in order to compress the whole image			*/
641 /*									*/
642 /*  1)  If the Current code is the initial value that serves to		*/
643 /*	flag this, set the current code to the first character to	*/
644 /*	compress. (and consume it)					*/
645 /*  2)  Make a new key to search the hash table.			*/
646 /*  3)  Lookup in hash table.						*/
647 /*  4)  If it is there, simply take the new code as the current code.	*/
648 /*  5)  If not, emit the current code and set the current code to the	*/
649 /*	pixel value.							*/
650 /*      If next code cannot fit into the current code size, must raise	*/
651 /*	the code size.							*/
652 /*  6)  BUT.. If the hash table is full, send a Clear code and clear	*/
653 /*	the hash table as well.						*/
654 /*									*/
655 /************************************************************************/
656 
sioOutLzwGifWriteBytes(void * voidlos,const unsigned char * buffer,int count)657 static int sioOutLzwGifWriteBytes(
658 				void *			voidlos,
659 				const unsigned char *	buffer,
660 				int			count )
661 {
662     LzwGifOutputStream *	los= (LzwGifOutputStream *)voidlos;
663     LzwState *			ls= &(los->losState);
664 
665     int				i= 0;
666 
667     /*  1  */
668     if  ( ls->lsCurrentCode == FIRST_CODE )
669 	{
670 	ls->lsCurrentCode=
671 		    buffer[i++] & SIO_LZW_OutMasks[ls->lsInitialCodeSize];
672 	}
673 
674     while( i < count )
675 	{
676 	int	val= buffer[i++] & SIO_LZW_OutMasks[ls->lsInitialCodeSize];
677 	int	nextKey;
678 	int	nextCode;
679 
680 	/*  2  */
681 	nextKey= ( ((unsigned long) ls->lsCurrentCode ) << 8) + val;
682 
683 	/*  3  */
684 	nextCode= _ExistsHashTable( &(los->losHashTable), nextKey );
685 
686 	/*  4  */
687 	if  ( nextCode >= 0 )
688 	    { ls->lsCurrentCode= nextCode;	}
689 	else{
690 	    /*  5  */
691 	    if  ( sioOutLzwGifWriteCode( los, ls->lsCurrentCode ) )
692 		{ LDEB(ls->lsCurrentCode); return -1;	}
693 
694 	    ls->lsCurrentCode= val;
695 
696 	    if  ( ls->lsNextCode >= ls->lsMaxCode1 )
697 		{ ls->lsMaxCode1= 1 << ++(ls->lsCurrentCodeSize);	}
698 
699 	    /*  6  */
700 	    if  ( ls->lsCurrentCodeSize > 12 )
701 		{
702 		ls->lsCurrentCodeSize= 12;
703 
704 		if  ( sioOutLzwGifWriteCode( los, ls->lsClearCode ) )
705 		    { LDEB(ls->lsCurrentCode); return -1;	}
706 
707 		ls->lsNextCode= ls->lsEOFCode+ 1;
708 		ls->lsCurrentCodeSize= ls->lsInitialCodeSize+ 1;
709 		ls->lsMaxCode1= 1 << ls->lsCurrentCodeSize;
710 
711 		_ClearHashTable( &(los->losHashTable) );
712 		}
713 	    else{
714 		_InsertHashTable( &(los->losHashTable),
715 					    nextKey, ls->lsNextCode );
716 		ls->lsNextCode++;
717 		}
718 	   }
719 	}
720 
721     return count;
722 }
723 
724 /************************************************************************/
725 /*									*/
726 /*  Open a 12 bit LZW output stream.					*/
727 /*									*/
728 /*  NOTE that the initial code size has been communicated outside the	*/
729 /*	compressed stream. In the GIF case even before the packeted	*/
730 /*	stream packet header of the first packet.			*/
731 /*									*/
732 /*  1)  Allocate memory and remember the output stream.			*/
733 /*  2)  Initialize the hash table by clearing it.			*/
734 /*  3)  Initialize the general LZW administration for the current code	*/
735 /*	size.								*/
736 /*  4)  General SioOut administration.					*/
737 /*  Z)  Start with a clear code to be sure that the decoder has also	*/
738 /*	cleared its hash table.						*/
739 /*									*/
740 /************************************************************************/
741 
sioOutLzwGifOpen(SimpleOutputStream * sosLzw,int codeSize)742 SimpleOutputStream * sioOutLzwGifOpen(	SimpleOutputStream *	sosLzw,
743 					int			codeSize )
744     {
745     SimpleOutputStream *	sos;
746     LzwGifOutputStream *	los;
747 
748     /*  1  */
749     los= (LzwGifOutputStream *)malloc( sizeof(LzwGifOutputStream) );
750     if  ( ! los )
751 	{ XDEB(los); return (SimpleOutputStream *)0;	}
752 
753     los->losSosLzw= sosLzw;
754 
755     /*  2  */
756     _ClearHashTable( &(los->losHashTable) );
757 
758     /*  3  */
759     sioLzwInitState( &(los->losState), codeSize );
760 
761     /*  4  */
762     sos= sioOutOpen( (void *)los, sioOutLzwGifWriteBytes, sioOutLzwGifClose );
763 
764     if  ( ! sos )
765 	{ XDEB(sos); free( los ); return (SimpleOutputStream *)0; }
766 
767     /*  Z  */
768     if  ( sioOutLzwGifWriteCode( los, los->losState.lsClearCode ) )
769 	{ LDEB(1); sioOutClose( sos ); return (SimpleOutputStream *)0; }
770 
771     return sos;
772     }
773 
774