1 /**
2  * File: GIF Output
3  *
4  * Write GIF images.
5  */
6 
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include <stdio.h>
12 #include <math.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include "gd.h"
16 #include "gdhelpers.h"
17 
18 /* Code drawn from ppmtogif.c, from the pbmplus package
19 **
20 ** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
21 ** Lempel-Zim compression based on "compress".
22 **
23 ** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
24 **
25 ** Copyright (C) 1989 by Jef Poskanzer.
26 **
27 ** Permission to use, copy, modify, and distribute this software and its
28 ** documentation for any purpose and without fee is hereby granted, provided
29 ** that the above copyright notice appear in all copies and that both that
30 ** copyright notice and this permission notice appear in supporting
31 ** documentation.  This software is provided "as is" without express or
32 ** implied warranty.
33 **
34 ** The Graphics Interchange Format(c) is the Copyright property of
35 ** CompuServe Incorporated.  GIF(sm) is a Service Mark property of
36 ** CompuServe Incorporated.
37 */
38 
39 /* a code_int must be able to hold 2**GIFBITS values of type int, and also -1 */
40 typedef int code_int;
41 
42 #ifdef SIGNED_COMPARE_SLOW
43 typedef unsigned long int count_int;
44 typedef unsigned short int count_short;
45 #else /* SIGNED_COMPARE_SLOW */
46 typedef long int count_int;
47 #endif /* SIGNED_COMPARE_SLOW */
48 
49 /* 2.0.28: threadsafe */
50 
51 #define maxbits GIFBITS
52 
53 /* should NEVER generate this code */
54 #define maxmaxcode ((code_int)1 << GIFBITS)
55 
56 #define HSIZE	5003	/* 80% occupancy */
57 #define hsize	HSIZE	/* Apparently invariant, left over from compress */
58 
59 typedef struct {
60 	int Width, Height;
61 	int curx, cury;
62 	long CountDown;
63 	int Pass;
64 	int Interlace;
65 	int n_bits;
66 	code_int maxcode;
67 	count_int htab [HSIZE];
68 	unsigned short codetab [HSIZE];
69 	/* first unused entry */
70 	code_int free_ent;
71 	/* block compression parameters -- after all codes are used up,
72 	 * and compression rate changes, start over. */
73 	int clear_flg;
74 	int offset;
75 	long int in_count;
76 	/* # of codes output (for debugging) */
77 	long int out_count;
78 	int g_init_bits;
79 	gdIOCtx * g_outfile;
80 	int ClearCode;
81 	int EOFCode;
82 	unsigned long cur_accum;
83 	int cur_bits;
84 	int a_count;
85 	char accum[ 256 ];
86 } GifCtx;
87 
88 static int gifPutWord(int w, gdIOCtx *out);
89 static int colorstobpp(int colors);
90 static void BumpPixel(GifCtx *ctx);
91 static int GIFNextPixel(gdImagePtr im, GifCtx *ctx);
92 static void GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
93 static void GIFAnimEncode(gdIOCtxPtr fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, int GInterlace, int Transparent, int Delay, int Disposal, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
94 static void compress(int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx);
95 static void output(code_int code, GifCtx *ctx);
96 static void cl_block(GifCtx *ctx);
97 static void cl_hash(register count_int chsize, GifCtx *ctx);
98 static void char_init(GifCtx *ctx);
99 static void char_out(int c, GifCtx *ctx);
100 static void flush_char(GifCtx *ctx);
101 
102 static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out);
103 static int _gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out,
104                                        int LocalCM, int LeftOfs, int TopOfs,
105                                        int Delay, int Disposal,
106                                        gdImagePtr previm);
107 
108 
109 
110 /*
111   Function: gdImageGifPtr
112 
113     Identical to <gdImageGif> except that it returns a pointer to a
114     memory area with the GIF data. This memory must be freed by the
115     caller when it is no longer needed.
116 
117     The caller *must* invoke <gdFree>, not _free()_.  This is because
118     it is not guaranteed that libgd will use the same implementation
119     of malloc, free, etc. as your proggram.
120 
121     The 'size' parameter receives the total size of the block of
122     memory.
123 
124   Parameters:
125 
126     im      - The image to write
127     size    - Output: the size of the resulting image.
128 
129   Returns:
130 
131     A pointer to the GIF data or NULL if an error occurred.
132 
133 */
gdImageGifPtr(gdImagePtr im,int * size)134 BGD_DECLARE(void *) gdImageGifPtr(gdImagePtr im, int *size)
135 {
136 	void *rv;
137 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
138 	if (out == NULL) return NULL;
139 	if (!_gdImageGifCtx(im, out)) {
140 		rv = gdDPExtractData(out, size);
141 	} else {
142 		rv = NULL;
143 	}
144 	out->gd_free(out);
145 	return rv;
146 }
147 
148 /*
149   Function: gdImageGif
150 
151     <gdImageGif> outputs the specified image to the specified file in
152     GIF format. The file must be open for binary writing. (Under MSDOS
153     and all versions of Windows, it is important to use "wb" as
154     opposed to simply "w" as the mode when opening the file; under
155     Unix there is no penalty for doing so). <gdImageGif> does not close
156     the file; your code must do so.
157 
158     GIF does not support true color; GIF images can contain a maximum
159     of 256 colors. If the image to be written is a truecolor image,
160     such as those created with gdImageCreateTrueColor or loaded from a
161     JPEG or a truecolor PNG image file, a palette-based temporary
162     image will automatically be created internally using the
163     <gdImageCreatePaletteFromTrueColor> function. The original image
164     pixels are not modified. This conversion produces high quality
165     palettes but does require some CPU time. If you are regularly
166     converting truecolor to palette in this way, you should consider
167     creating your image as a palette-based image in the first place.
168 
169   Variants:
170 
171     <gdImageGifCtx> outputs the image via a <gdIOCtx> struct.
172 
173     <gdImageGifPtr> stores the image in a large array of bytes.
174 
175   Parameters:
176 
177     im      - The image to write
178     outFile - The FILE pointer to write the image to.
179 
180   Returns:
181 
182     Nothing
183 
184   Example:
185 
186     > gdImagePtr im;
187     > int black, white;
188     > FILE *out;
189     > // Create the image
190     > im = gdImageCreate(100, 100);
191     > // Allocate background
192     > white = gdImageColorAllocate(im, 255, 255, 255);
193     > // Allocate drawing color
194     > black = gdImageColorAllocate(im, 0, 0, 0);
195     > // Draw rectangle
196     > gdImageRectangle(im, 0, 0, 99, 99, black);
197     > // Open output file in binary mode
198     > out = fopen("rect.gif", "wb");
199     > // Write GIF
200     > gdImageGif(im, out);
201     > // Close file
202     > fclose(out);
203     > // Destroy image
204     > gdImageDestroy(im);
205 
206 */
gdImageGif(gdImagePtr im,FILE * outFile)207 BGD_DECLARE(void) gdImageGif(gdImagePtr im, FILE *outFile)
208 {
209 	gdIOCtx *out = gdNewFileCtx(outFile);
210 	if (out == NULL) return;
211 	gdImageGifCtx(im, out);
212 	out->gd_free(out);
213 }
214 
215 /*
216   Function: gdImageGifCtx
217 
218     Writes a GIF image via a <gdIOCtx>.  See <gdImageGif>.
219 
220   Parameters:
221 
222     im      - The image to write
223     out     - The <gdIOCtx> struct used to do the writing.
224 
225   Returns:
226 
227     Nothing.
228 
229 */
gdImageGifCtx(gdImagePtr im,gdIOCtxPtr out)230 BGD_DECLARE(void) gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
231 {
232 	_gdImageGifCtx(im, out);
233 }
234 
235 /* returns 0 on success, 1 on failure */
_gdImageGifCtx(gdImagePtr im,gdIOCtxPtr out)236 static int _gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
237 {
238 	gdImagePtr pim = 0, tim = im;
239 	int interlace, BitsPerPixel;
240 	interlace = im->interlace;
241 
242 	if(im->trueColor) {
243 		/* Expensive, but the only way that produces an
244 		acceptable result: mix down to a palette
245 		based temporary image. */
246 		pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
247 		if(!pim) {
248 			return 1;
249 		}
250 		tim = pim;
251 	}
252 
253 	BitsPerPixel = colorstobpp(tim->colorsTotal);
254 
255 	/* All set, let's do it. */
256 	GIFEncode(
257 	    out, tim->sx, tim->sy, interlace, 0, tim->transparent, BitsPerPixel,
258 	    tim->red, tim->green, tim->blue, tim);
259 
260 	if(pim) {
261 		/* Destroy palette based temporary image. */
262 		gdImageDestroy(	pim);
263 	}
264 
265 	return 0;
266 }
267 
268 
269 /*
270   Function: gdImageGifAnimBeginPtr
271 
272     Like <gdImageGifAnimBegin> except that it outputs to a memory
273     buffer.  See <gdImageGifAnimBegin>.
274 
275     The returned memory must be freed by the caller when it is no
276     longer needed. **The caller must invoke <gdFree>(), not free()**,
277     unless the caller is absolutely certain that the same
278     implementations of malloc, free, etc. are used both at library
279     build time and at application build time (but don't; it could
280     always change).
281 
282     The 'size' parameter receives the total size of the block of
283     memory.
284 
285   Parameters:
286 
287     im          - The reference image
288     size        - Output: the size in bytes of the result.
289     GlobalCM    - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default
290     Loops       - Loop count; 0 -> infinite, -1 means no loop
291 
292   Returns:
293 
294    A pointer to the resulting data (the contents of the start of the
295    GIF) or NULL if an error occurred.
296 
297 */
298 
gdImageGifAnimBeginPtr(gdImagePtr im,int * size,int GlobalCM,int Loops)299 BGD_DECLARE(void *) gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM, int Loops)
300 {
301 	void *rv;
302 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
303 	if (out == NULL) return NULL;
304 	gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops);
305 	rv = gdDPExtractData(out, size);
306 	out->gd_free(out);
307 	return rv;
308 }
309 
310 
311 /*
312   Function: gdImageGifAnimBegin
313 
314     This function must be called as the first function when creating a
315     GIF animation. It writes the correct GIF file headers to selected
316     file output, and prepares for frames to be added for the
317     animation. The image argument is not used to produce an image
318     frame to the file, it is only used to establish the GIF animation
319     frame size, interlacing options and the color
320     palette. <gdImageGifAnimAdd> is used to add the first and
321     subsequent frames to the animation, and the animation must be
322     terminated by writing a semicolon character (;) to it or by using
323     gdImageGifAnimEnd to do that.
324 
325     The GlobalCM flag indicates if a global color map (or palette) is
326     used in the GIF89A header. A nonzero value specifies that a global
327     color map should be used to reduce the size of the animation. Of
328     course, if the color maps of individual frames differ greatly, a
329     global color map may not be a good idea. GlobalCM=1 means write
330     global color map, GlobalCM=0 means do not, and GlobalCM=-1 means
331     to do the default, which currently is to use a global color map.
332 
333     If Loops is 0 or greater, the Netscape 2.0 extension for animation
334     loop count is written. 0 means infinite loop count. -1 means that
335     the extension is not added which results in no looping. -1 is the
336     default.
337 
338   Variants:
339 
340     <gdImageGifAnimBeginCtx> outputs the image via a <gdIOCtx> struct.
341 
342     <gdImageGifAnimBeginPtr> stores the image in a large array of bytes.
343 
344   Parameters:
345 
346     im          - The reference image
347     outfile     - The output FILE*.
348     GlobalCM    - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default
349     Loops       - Loop count; 0 -> infinite, -1 means no loop
350 
351   Returns:
352 
353     Nothing.
354 
355   Example:
356 
357     See <gdImageGifAnimBegin>.
358 
359 */
360 
gdImageGifAnimBegin(gdImagePtr im,FILE * outFile,int GlobalCM,int Loops)361 BGD_DECLARE(void) gdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops)
362 {
363 	gdIOCtx *out = gdNewFileCtx(outFile);
364 	if (out == NULL) return;
365 	gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops);
366 	out->gd_free(out);
367 }
368 
369 
370 
371 /*
372   Function: gdImageGifAnimBeginCtx
373 
374     Like <gdImageGifAnimBegin> except that it outputs to <gdIOCtx>.
375     See <gdImageGifAnimBegin>.
376 
377   Parameters:
378 
379     im          - The reference image
380     out         - Pointer to the output <gdIOCtx>.
381     GlobalCM    - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default
382     Loops       - Loop count; 0 -> infinite, -1 means no loop
383 
384   Returns:
385 
386     Nothing.
387 
388 */
gdImageGifAnimBeginCtx(gdImagePtr im,gdIOCtxPtr out,int GlobalCM,int Loops)389 BGD_DECLARE(void) gdImageGifAnimBeginCtx(gdImagePtr im, gdIOCtxPtr out, int GlobalCM, int Loops)
390 {
391 	int B;
392 	int RWidth, RHeight;
393 	int Resolution;
394 	int ColorMapSize;
395 	int BitsPerPixel;
396 	int Background = 0;
397 	int i;
398 
399 	/* Default is to use global color map */
400 	if (GlobalCM < 0) {
401 		GlobalCM = 1;
402 	}
403 
404 	BitsPerPixel = colorstobpp(im->colorsTotal);
405 	ColorMapSize = 1 << BitsPerPixel;
406 
407 	RWidth = im->sx;
408 	RHeight = im->sy;
409 
410 	Resolution = BitsPerPixel;
411 
412 	/* Write the Magic header */
413 	gdPutBuf("GIF89a", 6, out);
414 
415 	/* Write out the screen width and height */
416 	gifPutWord(RWidth, out);
417 	gifPutWord(RHeight, out);
418 
419 	/* Indicate that there is a global colour map */
420 	B = GlobalCM ? 0x80 : 0;
421 
422 	/* OR in the resolution */
423 	B |= (Resolution - 1) << 4;
424 
425 	/* OR in the Bits per Pixel */
426 	B |= (BitsPerPixel - 1);
427 
428 	/* Write it out */
429 	gdPutC(B, out);
430 
431 	/* Write out the Background colour */
432 	gdPutC(Background, out);
433 
434 	/* Byte of 0's (future expansion) */
435 	gdPutC(0, out);
436 
437 	/* Write out the Global Colour Map */
438 	if(GlobalCM) {
439 		for(i = 0; i < ColorMapSize; ++i) {
440 			gdPutC(im->red[i], out);
441 			gdPutC(im->green[i], out);
442 			gdPutC(im->blue[i], out);
443 		}
444 	}
445 
446 	if(Loops >= 0) {
447 		gdPutBuf("!\377\13NETSCAPE2.0\3\1", 16, out);
448 		gifPutWord(Loops, out);
449 		gdPutC(0, out);
450 	}
451 }
452 
453 
454 
455 /*
456   Function: gdImageGifAnimAddPtr
457 
458     Like <gdImageGifAnimAdd> (which contains more information) except
459     that it stores the data to write into memory and returns a pointer
460     to it.
461 
462     This memory must be freed by the caller when it is no longer
463     needed. **The caller must invoke <gdFree>(), not free(),** unless
464     the caller is absolutely certain that the same implementations of
465     malloc, free, etc. are used both at library build time and at
466     application build time (but don't; it could always change).
467 
468     The 'size' parameter receives the total size of the block of
469     memory.
470 
471   Parameters:
472 
473     im          - The image to add.
474     size        - Output: the size of the resulting buffer.
475     LocalCM     - Flag.  If 1, use a local color map for this frame.
476     LeftOfs     - Left offset of image in frame.
477     TopOfs      - Top offset of image in frame.
478     Delay       - Delay before next frame (in 1/100 seconds)
479     Disposal    - MODE: How to treat this frame when the next one loads.
480     previm      - NULL or a pointer to the previous image written.
481 
482   Returns:
483 
484     Pointer to the resulting data or NULL if an error occurred.
485 
486 */
gdImageGifAnimAddPtr(gdImagePtr im,int * size,int LocalCM,int LeftOfs,int TopOfs,int Delay,int Disposal,gdImagePtr previm)487 BGD_DECLARE(void *) gdImageGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM,
488                                          int LeftOfs, int TopOfs, int Delay,
489                                          int Disposal, gdImagePtr previm)
490 {
491 	void *rv;
492 	gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
493 	if (out == NULL) return NULL;
494 	if (!_gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm)) {
495 		rv = gdDPExtractData(out, size);
496 	} else {
497 		rv = NULL;
498 	}
499 	out->gd_free(out);
500 	return rv;
501 }
502 
503 
504 /*
505   Function: gdImageGifAnimAdd
506 
507     This function writes GIF animation frames to GIF animation, which
508     was initialized with <gdImageGifAnimBegin>. With _LeftOfs_ and
509     _TopOfs_ you can place this frame in different offset than (0,0)
510     inside the image screen as defined in <gdImageGifAnimBegin>. Delay
511     between the previous frame and this frame is in 1/100s
512     units. _Disposal_ is usually <gdDisposalNone>, meaning that the
513     pixels changed by this frame should remain on the display when the
514     next frame begins to render, but can also be <gdDisposalUnknown>
515     (not recommended), <gdDisposalRestoreBackground> (restores the
516     first allocated color of the global palette), or
517     <gdDisposalRestorePrevious> (restores the appearance of the
518     affected area before the frame was rendered). Only
519     <gdDisposalNone> is a sensible choice for the first frame. If
520     _previm_ is passed, the built-in GIF optimizer will always use
521     <gdDisposalNone> regardless of the Disposal parameter.
522 
523     Setting the _LocalCM_ flag to 1 adds a local palette for this
524     image to the animation. Otherwise the global palette is assumed
525     and the user must make sure the palettes match. Use
526     <gdImagePaletteCopy> to do that.
527 
528     Automatic optimization is activated by giving the previous image
529     as a parameter. This function then compares the images and only
530     writes the changed pixels to the new frame in animation. The
531     _Disposal_ parameter for optimized animations must be set to 1,
532     also for the first frame. _LeftOfs_ and _TopOfs_ parameters are
533     ignored for optimized frames. To achieve good optimization, it is
534     usually best to use a single global color map. To allow
535     <gdImageGifAnimAdd> to compress unchanged pixels via the use of a
536     transparent color, the image must include a transparent color.
537 
538 
539   Variants:
540 
541     <gdImageGifAnimAddCtx> outputs its data via a <gdIOCtx> struct.
542 
543     <gdImageGifAnimAddPtr> outputs its data to a memory buffer which
544     it returns.
545 
546   Parameters:
547 
548     im          - The image to add.
549     outfile     - The output FILE* being written.
550     LocalCM     - Flag.  If 1, use a local color map for this frame.
551     LeftOfs     - Left offset of image in frame.
552     TopOfs      - Top offset of image in frame.
553     Delay       - Delay before next frame (in 1/100 seconds)
554     Disposal    - MODE: How to treat this frame when the next one loads.
555     previm      - NULL or a pointer to the previous image written.
556 
557   Returns:
558 
559     Nothing.
560 
561   Example:
562     (start code)
563 
564     {
565     gdImagePtr im, im2, im3;
566     int black, white, trans;
567     FILE *out;
568 
569     im = gdImageCreate(100, 100);     // Create the image
570     white = gdImageColorAllocate(im, 255, 255, 255); // Allocate background
571     black = gdImageColorAllocate(im, 0, 0, 0); // Allocate drawing color
572     trans = gdImageColorAllocate(im, 1, 1, 1); // trans clr for compression
573     gdImageRectangle(im, 0, 0, 10, 10, black); // Draw rectangle
574 
575     out = fopen("anim.gif", "wb");// Open output file in binary mode
576     gdImageGifAnimBegin(im, out, 1, 3);// Write GIF hdr, global clr map,loops
577     // Write the first frame.  No local color map.  Delay = 1s
578     gdImageGifAnimAdd(im, out, 0, 0, 0, 100, 1, NULL);
579 
580     // construct the second frame
581     im2 = gdImageCreate(100, 100);
582     (void)gdImageColorAllocate(im2, 255, 255, 255); // White background
583     gdImagePaletteCopy (im2, im);  // Make sure the palette is identical
584     gdImageRectangle(im2, 0, 0, 15, 15, black);    // Draw something
585     // Allow animation compression with transparent pixels
586     gdImageColorTransparent (im2, trans);
587     gdImageGifAnimAdd(im2, out, 0, 0, 0, 100, 1, im);  // Add second frame
588 
589     // construct the third frame
590     im3 = gdImageCreate(100, 100);
591     (void)gdImageColorAllocate(im3, 255, 255, 255); // white background
592     gdImagePaletteCopy (im3, im); // Make sure the palette is identical
593     gdImageRectangle(im3, 0, 0, 15, 20, black); // Draw something
594     // Allow animation compression with transparent pixels
595     gdImageColorTransparent (im3, trans);
596     // Add the third frame, compressing against the second one
597     gdImageGifAnimAdd(im3, out, 0, 0, 0, 100, 1, im2);
598     gdImageGifAnimEnd(out);  // End marker, same as putc(';', out);
599     fclose(out); // Close file
600 
601     // Destroy images
602     gdImageDestroy(im);
603     gdImageDestroy(im2);
604     gdImageDestroy(im3);
605     }
606 
607     (end code)
608 */
609 
gdImageGifAnimAdd(gdImagePtr im,FILE * outFile,int LocalCM,int LeftOfs,int TopOfs,int Delay,int Disposal,gdImagePtr previm)610 BGD_DECLARE(void) gdImageGifAnimAdd(gdImagePtr im, FILE *outFile, int LocalCM,
611                                     int LeftOfs, int TopOfs, int Delay,
612                                     int Disposal, gdImagePtr previm)
613 {
614 	gdIOCtx *out = gdNewFileCtx(outFile);
615 	if (out == NULL) return;
616 	gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm);
617 	out->gd_free(out);
618 }
619 
comparewithmap(gdImagePtr im1,gdImagePtr im2,int c1,int c2,int * colorMap)620 static int comparewithmap(gdImagePtr im1, gdImagePtr im2, int c1, int c2, int *colorMap)
621 {
622 	if(!colorMap) {
623 		return c1 == c2;
624 	}
625 
626 	if(-2 != colorMap[c1]) {
627 		return colorMap[c1] == c2;
628 	}
629 
630 	return (colorMap[c1] = gdImageColorExactAlpha(im2, im1->red[c1], im1->green[c1], im1->blue[c1], im1->alpha[c1])) == c2;
631 }
632 
633 /*
634   Function: gdImageGifAnimAddCtx
635 
636     Adds an animation frame via a <gdIOCtxPtr>.  See gdImageGifAnimAdd>.
637 
638   Parameters:
639 
640     im          - The image to add.
641     out         - The output <gdIOCtxPtr>.
642     LocalCM     - Flag.  If 1, use a local color map for this frame.
643     LeftOfs     - Left offset of image in frame.
644     TopOfs      - Top offset of image in frame.
645     Delay       - Delay before next frame (in 1/100 seconds)
646     Disposal    - MODE: How to treat this frame when the next one loads.
647     previm      - NULL or a pointer to the previous image written.
648 
649   Returns:
650 
651     Nothing.
652 
653 */
gdImageGifAnimAddCtx(gdImagePtr im,gdIOCtxPtr out,int LocalCM,int LeftOfs,int TopOfs,int Delay,int Disposal,gdImagePtr previm)654 BGD_DECLARE(void) gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out,
655                                        int LocalCM, int LeftOfs, int TopOfs,
656                                        int Delay, int Disposal,
657                                        gdImagePtr previm)
658 {
659 	_gdImageGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal, previm);
660 }
661 
662 /* returns 0 on success, 1 on failure */
_gdImageGifAnimAddCtx(gdImagePtr im,gdIOCtxPtr out,int LocalCM,int LeftOfs,int TopOfs,int Delay,int Disposal,gdImagePtr previm)663 static int _gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out,
664                                        int LocalCM, int LeftOfs, int TopOfs,
665                                        int Delay, int Disposal,
666                                        gdImagePtr previm)
667 {
668 	gdImagePtr pim = NULL, tim = im;
669 	int interlace, transparent, BitsPerPixel;
670 	interlace = im->interlace;
671 	transparent = im->transparent;
672 
673 	/* Default is no local color map */
674 	if(LocalCM < 0) {
675 		LocalCM = 0;
676 	}
677 
678 	if(im->trueColor) {
679 		/* Expensive, but the only way that produces an
680 			acceptable result: mix down to a palette
681 			based temporary image. */
682 		pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
683 		if (!pim) {
684 			return 1;
685 		}
686 		tim = pim;
687 	}
688 
689 	if (previm) {
690 		/* create optimized animation.  Compare this image to
691 		   the previous image and crop the temporary copy of
692 		   current image to include only changed rectangular
693 		   area.  Also replace unchanged pixels inside this
694 		   area with transparent color.  Transparent color
695 		   needs to be already allocated!
696 		   Preconditions:
697 		   TopOfs, LeftOfs are assumed 0
698 
699 		   Images should be of same size.  If not, a temporary
700 		   copy is made with the same size as previous image.
701 
702 		*/
703 		gdImagePtr prev_pim = 0, prev_tim = previm;
704 		int x, y;
705 		int min_x = 0;
706 		int min_y = tim->sy;
707 		int max_x = 0;
708 		int max_y = 0;
709 		int colorMap[256];
710 
711 		if (previm->trueColor) {
712 			prev_pim = gdImageCreatePaletteFromTrueColor(previm, 1, 256);
713 			if (!prev_pim) {
714 				goto fail_end;
715 			}
716 			prev_tim = prev_pim;
717 		}
718 
719 		for (x = 0; x < 256; ++x) {
720 			colorMap[x] = -2;
721 		}
722 
723 		/* First find bounding box of changed areas. */
724 		/* first find the top changed row */
725 		for (y = 0; y < tim->sy; ++y) {
726 			for (x = 0; x < tim->sx; ++x) {
727 				if (!comparewithmap(prev_tim, tim,
728 				                    prev_tim->pixels[y][x],
729 				                    tim->pixels[y][x],
730 				                    colorMap)) {
731 					min_y = max_y = y;
732 					min_x = max_x = x;
733 					goto break_top;
734 				}
735 			}
736 		}
737 
738 break_top:
739 		if (tim->sy == min_y) {
740 			/* No changes in this frame!! Encode empty image. */
741 			transparent = 0;
742 			min_x = min_y = 1;
743 			max_x = max_y = 0;
744 		} else {
745 			/* Then the bottom row */
746 			for (y = tim->sy - 1; y > min_y; --y) {
747 				for (x = 0; x < tim->sx; ++x) {
748 					if (!comparewithmap
749 					        (prev_tim, tim,
750 					         prev_tim->pixels[y][x],
751 					         tim->pixels[y][x],
752 					         colorMap)) {
753 						max_y = y;
754 						if(x < min_x) {
755 							min_x = x;
756 						}
757 						if(x > max_x) {
758 							max_x = x;
759 						}
760 						goto break_bot;
761 					}
762 				}
763 			}
764 
765 break_bot:
766 			/* left side */
767 			for (x = 0; x < min_x; ++x) {
768 				for (y = min_y; y <= max_y; ++y) {
769 					if (!comparewithmap
770 					        (prev_tim, tim,
771 					         prev_tim->pixels[y][x],
772 					         tim->pixels[y][x],
773 					         colorMap)) {
774 						min_x = x;
775 						goto break_left;
776 					}
777 				}
778 			}
779 
780 break_left:
781 			/* right side */
782 			for (x = tim->sx - 1; x > max_x; --x) {
783 				for (y = min_y; y <= max_y; ++y) {
784 					if (!comparewithmap
785 					        (prev_tim, tim,
786 					         prev_tim->pixels[y][x],
787 					         tim->pixels[y][x],
788 					         colorMap)) {
789 						max_x = x;
790 						goto break_right;
791 					}
792 				}
793 			}
794 
795 break_right:
796 			;
797 		}
798 
799 		LeftOfs = min_x;
800 		TopOfs = min_y;
801 		Disposal = 1;
802 
803 		/* Make a copy of the image with the new offsets.
804 		   But only if necessary. */
805 		if (min_x != 0 || max_x != tim->sx - 1
806 		        || min_y != 0 || max_y != tim->sy - 1
807 		        || transparent >= 0) {
808 
809 			gdImagePtr pim2 = gdImageCreate(max_x-min_x + 1, max_y-min_y + 1);
810 
811 			if (!pim2) {
812 				if (prev_pim) {
813 					gdImageDestroy(prev_pim);
814 				}
815 				goto fail_end;
816 			}
817 
818 			gdImagePaletteCopy(pim2, LocalCM ? tim : prev_tim);
819 			gdImageCopy(pim2, tim, 0, 0, min_x, min_y,
820 			            max_x - min_x + 1, max_y - min_y + 1);
821 
822 			if (pim) {
823 				gdImageDestroy(pim);
824 			}
825 
826 			tim = pim = pim2;
827 		}
828 
829 		/* now let's compare pixels for transparent
830 		   optimization.  But only if transparent is set. */
831 		if (transparent >= 0) {
832 			for(y = 0; y < tim->sy; ++y) {
833 				for (x = 0; x < tim->sx; ++x) {
834 					if(comparewithmap
835 					        (prev_tim, tim,
836 					         prev_tim->pixels[min_y + y][min_x + x],
837 					         tim->pixels[y][x], 0)) {
838 						gdImageSetPixel(tim, x, y, transparent);
839 						break;
840 					}
841 				}
842 			}
843 		}
844 
845 		if(prev_pim) {
846 			gdImageDestroy(prev_pim);
847 		}
848 	}
849 
850 	BitsPerPixel = colorstobpp(tim->colorsTotal);
851 
852 	/* All set, let's do it. */
853 	GIFAnimEncode(
854 	    out, tim->sx, tim->sy, LeftOfs, TopOfs, interlace, transparent,
855 	    Delay, Disposal, BitsPerPixel,
856 	    LocalCM ? tim->red : 0, tim->green, tim->blue, tim);
857 	return 0;
858 
859 fail_end:
860 	if(pim) {
861 		/* Destroy palette based temporary image. */
862 		gdImageDestroy(pim);
863 	}
864 	return 1;
865 }
866 
867 
868 
869 /*
870   Function: gdImageGifAnimEnd
871 
872     Terminates the GIF file properly.
873 
874     (Previous versions of this function's documentation suggested just
875     manually writing a semicolon (';') instead since that is all this
876     function does.  While that has no longer changed, we now suggest
877     that you do not do this and instead always call
878     <gdImageGifAnimEnd> (or equivalent) since later versions could
879     possibly do more or different things.)
880 
881   Variants:
882 
883     <gdImageGifAnimEndCtx> outputs its data via a <gdIOCtx> struct.
884 
885     <gdImageGifAnimEndPtr> outputs its data to a memory buffer which
886     it returns.
887 
888   Parameters:
889 
890     outfile     - the destination FILE*.
891 
892   Returns:
893 
894     Nothing.
895 
896 */
897 
gdImageGifAnimEnd(FILE * outFile)898 BGD_DECLARE(void) gdImageGifAnimEnd(FILE *outFile)
899 {
900 #if 1
901 	putc(';', outFile);
902 #else
903 	gdIOCtx *out = gdNewFileCtx(outFile);
904 	if (out == NULL) return;
905 	gdImageGifAnimEndCtx(out);
906 	out->gd_free(out);
907 #endif
908 }
909 
910 /*
911   Function: gdImageGifAnimEndPtr
912 
913     Like <gdImageGifAnimEnd> (which contains more information) except
914     that it stores the data to write into memory and returns a pointer
915     to it.
916 
917     This memory must be freed by the caller when it is no longer
918     needed. **The caller must invoke <gdFree>(), not free(),** unless
919     the caller is absolutely certain that the same implementations of
920     malloc, free, etc. are used both at library build time and at
921     application build time (but don't; it could always change).
922 
923     The 'size' parameter receives the total size of the block of
924     memory.
925 
926   Parameters:
927 
928     size        - Output: the size of the resulting buffer.
929 
930   Returns:
931 
932     Pointer to the resulting data or NULL if an error occurred.
933 
934 */
935 
gdImageGifAnimEndPtr(int * size)936 BGD_DECLARE(void *) gdImageGifAnimEndPtr(int *size)
937 {
938 	char *rv = (char *) gdMalloc(1);
939 	if(!rv) {
940 		return 0;
941 	}
942 	*rv = ';';
943 	*size = 1;
944 	return (void *)rv;
945 }
946 
947 /*
948   Function: gdImageGifAnimEndCtx
949 
950     Like <gdImageGifAnimEnd>, but writes its data via a <gdIOCtx>.
951 
952   Parameters:
953 
954     out         - the destination <gdIOCtx>.
955 
956   Returns:
957 
958     Nothing.
959 
960 */
961 
gdImageGifAnimEndCtx(gdIOCtx * out)962 BGD_DECLARE(void) gdImageGifAnimEndCtx(gdIOCtx *out)
963 {
964 	/*
965 	 * Write the GIF file terminator
966 	 */
967 	gdPutC(';', out);
968 }
969 
colorstobpp(int colors)970 static int colorstobpp(int colors)
971 {
972 	int bpp = 0;
973 
974 	if(colors <= 2)
975 		bpp = 1;
976 	else if(colors <= 4)
977 		bpp = 2;
978 	else if(colors <= 8)
979 		bpp = 3;
980 	else if(colors <= 16)
981 		bpp = 4;
982 	else if(colors <= 32)
983 		bpp = 5;
984 	else if(colors <= 64)
985 		bpp = 6;
986 	else if(colors <= 128)
987 		bpp = 7;
988 	else if(colors <= 256)
989 		bpp = 8;
990 
991 	return bpp;
992 }
993 
994 /*****************************************************************************
995  *
996  * GIFENCODE.C    - GIF Image compression interface
997  *
998  * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
999  *            BitsPerPixel, Red, Green, Blue, gdImagePtr )
1000  *
1001  *****************************************************************************/
1002 
1003 #define TRUE 1
1004 #define FALSE 0
1005 
1006 /* Bump the 'curx' and 'cury' to point to the next pixel */
BumpPixel(GifCtx * ctx)1007 static void BumpPixel(GifCtx *ctx)
1008 {
1009 	/* Bump the current X position */
1010 	++(ctx->curx);
1011 
1012 	/* If we are at the end of a scan line, set curx back to the beginning
1013 	 * If we are interlaced, bump the cury to the appropriate spot,
1014 	 * otherwise, just increment it. */
1015 	if(ctx->curx == ctx->Width) {
1016 		ctx->curx = 0;
1017 
1018 		if(!ctx->Interlace) {
1019 			++(ctx->cury);
1020 		} else {
1021 			switch(ctx->Pass) {
1022 
1023 			case 0:
1024 				ctx->cury += 8;
1025 				if(ctx->cury >= ctx->Height) {
1026 					++(ctx->Pass);
1027 					ctx->cury = 4;
1028 				}
1029 				break;
1030 
1031 			case 1:
1032 				ctx->cury += 8;
1033 				if(ctx->cury >= ctx->Height) {
1034 					++(ctx->Pass);
1035 					ctx->cury = 2;
1036 				}
1037 				break;
1038 
1039 			case 2:
1040 				ctx->cury += 4;
1041 				if(ctx->cury >= ctx->Height) {
1042 					++(ctx->Pass);
1043 					ctx->cury = 1;
1044 				}
1045 				break;
1046 
1047 			case 3:
1048 				ctx->cury += 2;
1049 				break;
1050 			}
1051 		}
1052 	}
1053 }
1054 
1055 /* Return the next pixel from the image */
GIFNextPixel(gdImagePtr im,GifCtx * ctx)1056 static int GIFNextPixel(gdImagePtr im, GifCtx *ctx)
1057 {
1058 	int r;
1059 
1060 	if(ctx->CountDown == 0) {
1061 		return EOF;
1062 	}
1063 
1064 	--(ctx->CountDown);
1065 
1066 	r = gdImageGetPixel(im, ctx->curx, ctx->cury);
1067 
1068 	BumpPixel(ctx);
1069 
1070 	return r;
1071 }
1072 
1073 /* public */
1074 
GIFEncode(gdIOCtxPtr fp,int GWidth,int GHeight,int GInterlace,int Background,int Transparent,int BitsPerPixel,int * Red,int * Green,int * Blue,gdImagePtr im)1075 static void GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
1076 {
1077 	int B;
1078 	int RWidth, RHeight;
1079 	int LeftOfs, TopOfs;
1080 	int Resolution;
1081 	int ColorMapSize;
1082 	int InitCodeSize;
1083 	int i;
1084 	GifCtx ctx;
1085 
1086 	memset(&ctx, 0, sizeof(ctx));
1087 
1088 	ctx.Interlace = GInterlace;
1089 	ctx.in_count = 1;
1090 
1091 	ColorMapSize = 1 << BitsPerPixel;
1092 
1093 	RWidth = ctx.Width = GWidth;
1094 	RHeight = ctx.Height = GHeight;
1095 	LeftOfs = TopOfs = 0;
1096 
1097 	Resolution = BitsPerPixel;
1098 
1099 	/* Calculate number of bits we are expecting */
1100 	ctx.CountDown = (long)ctx.Width * (long)ctx.Height;
1101 
1102 	/* Indicate which pass we are on (if interlace) */
1103 	ctx.Pass = 0;
1104 
1105 	/* The initial code size */
1106 	if(BitsPerPixel <= 1) {
1107 		InitCodeSize = 2;
1108 	} else {
1109 		InitCodeSize = BitsPerPixel;
1110 	}
1111 
1112 	/* Set up the current x and y position */
1113 	ctx.curx = ctx.cury = 0;
1114 
1115 	/* Write the Magic header */
1116 	gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp);
1117 
1118 	/* Write out the screen width and height */
1119 	gifPutWord(RWidth, fp);
1120 	gifPutWord(RHeight, fp);
1121 
1122 	/* Indicate that there is a global colour map */
1123 	/* Yes, there is a color map */
1124 	B = 0x80;
1125 
1126 	/* OR in the resolution */
1127 	B |= (Resolution - 1) << 4;
1128 
1129 	/* OR in the Bits per Pixel */
1130 	B |= (BitsPerPixel - 1);
1131 
1132 	/* Write it out */
1133 	gdPutC(B, fp);
1134 
1135 	/* Write out the Background colour */
1136 	gdPutC(Background, fp);
1137 
1138 	/* Byte of 0's (future expansion) */
1139 	gdPutC(0, fp);
1140 
1141 	/* Write out the Global Colour Map */
1142 	for(i = 0; i < ColorMapSize; ++i) {
1143 		gdPutC(Red[i], fp);
1144 		gdPutC(Green[i], fp);
1145 		gdPutC(Blue[i], fp);
1146 	}
1147 
1148 	/* Write out extension for transparent colour index, if necessary. */
1149 	if(Transparent >= 0) {
1150 		gdPutC('!', fp);
1151 		gdPutC(0xf9, fp);
1152 		gdPutC(4, fp);
1153 		gdPutC(1, fp);
1154 		gdPutC(0, fp);
1155 		gdPutC(0, fp);
1156 		gdPutC((unsigned char) Transparent, fp);
1157 		gdPutC(0, fp);
1158 	}
1159 
1160 	/* Write an Image separator */
1161 	gdPutC(',', fp);
1162 
1163 	/* Write the Image header */
1164 	gifPutWord(LeftOfs, fp);
1165 	gifPutWord(TopOfs, fp);
1166 	gifPutWord(ctx.Width, fp);
1167 	gifPutWord(ctx.Height, fp);
1168 
1169 	/* Write out whether or not the image is interlaced */
1170 	if(ctx.Interlace) {
1171 		gdPutC(0x40, fp);
1172 	} else {
1173 		gdPutC(0x00, fp);
1174 	}
1175 
1176 	/* Write out the initial code size */
1177 	gdPutC(InitCodeSize, fp);
1178 
1179 	/* Go and actually compress the data */
1180 	compress(InitCodeSize + 1, fp, im, &ctx);
1181 
1182 	/* Write out a Zero-length packet (to end the series) */
1183 	gdPutC(0, fp);
1184 
1185 	/* Write the GIF file terminator */
1186 	gdPutC(';', fp);
1187 }
1188 
GIFAnimEncode(gdIOCtxPtr fp,int IWidth,int IHeight,int LeftOfs,int TopOfs,int GInterlace,int Transparent,int Delay,int Disposal,int BitsPerPixel,int * Red,int * Green,int * Blue,gdImagePtr im)1189 static void GIFAnimEncode(gdIOCtxPtr fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, int GInterlace, int Transparent, int Delay, int Disposal, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
1190 {
1191 	int B;
1192 	int ColorMapSize;
1193 	int InitCodeSize;
1194 	int i;
1195 	GifCtx ctx;
1196 
1197 	memset(&ctx, 0, sizeof(ctx));
1198 
1199 	ctx.Interlace = GInterlace;
1200 	ctx.in_count = 1;
1201 
1202 	ColorMapSize = 1 << BitsPerPixel;
1203 
1204 	if(LeftOfs < 0) {
1205 		LeftOfs = 0;
1206 	}
1207 	if(TopOfs < 0) {
1208 		TopOfs = 0;
1209 	}
1210 	if(Delay < 0) {
1211 		Delay = 100;
1212 	}
1213 	if(Disposal < 0) {
1214 		Disposal = 1;
1215 	}
1216 
1217 	ctx.Width = IWidth;
1218 	ctx.Height = IHeight;
1219 
1220 	/* Calculate number of bits we are expecting */
1221 	ctx.CountDown = (long)ctx.Width * (long)ctx.Height;
1222 
1223 	/* Indicate which pass we are on (if interlace) */
1224 	ctx.Pass = 0;
1225 
1226 	/* The initial code size */
1227 	if(BitsPerPixel <= 1) {
1228 		InitCodeSize = 2;
1229 	} else {
1230 		InitCodeSize = BitsPerPixel;
1231 	}
1232 
1233 	/* Set up the current x and y position */
1234 	ctx.curx = ctx.cury = 0;
1235 
1236 	/* Write out extension for image animation and looping */
1237 	gdPutC('!', fp);
1238 	gdPutC(0xf9, fp);
1239 	gdPutC(4, fp);
1240 	gdPutC((Transparent >= 0 ? 1 : 0) | (Disposal << 2), fp);
1241 	gdPutC((unsigned char)(Delay & 255), fp);
1242 	gdPutC((unsigned char)((Delay >> 8) & 255), fp);
1243 	gdPutC((unsigned char) Transparent, fp);
1244 	gdPutC(0, fp);
1245 
1246 	/* Write an Image separator */
1247 	gdPutC(',', fp);
1248 
1249 	/* Write out the Image header */
1250 	gifPutWord(LeftOfs, fp);
1251 	gifPutWord(TopOfs, fp);
1252 	gifPutWord(ctx.Width, fp);
1253 	gifPutWord(ctx.Height, fp);
1254 
1255 	/* Indicate that there is a local colour map */
1256 	B = (Red && Green && Blue) ? 0x80 : 0;
1257 
1258 	/* OR in the interlacing */
1259 	B |= ctx.Interlace ? 0x40 : 0;
1260 
1261 	/* OR in the Bits per Pixel */
1262 	B |= (Red && Green && Blue) ? (BitsPerPixel - 1) : 0;
1263 
1264 	/* Write it out */
1265 	gdPutC(B, fp);
1266 
1267 	/* Write out the Local Colour Map */
1268 	if(Red && Green && Blue) {
1269 		for(i = 0; i < ColorMapSize; ++i) {
1270 			gdPutC(Red[i], fp);
1271 			gdPutC(Green[i], fp);
1272 			gdPutC(Blue[i], fp);
1273 		}
1274 	}
1275 
1276 	/* Write out the initial code size */
1277 	gdPutC(InitCodeSize, fp);
1278 
1279 	/* Go and actually compress the data */
1280 	compress(InitCodeSize + 1, fp, im, &ctx);
1281 
1282 	/* Write out a Zero-length packet (to end the series) */
1283 	gdPutC(0, fp);
1284 }
1285 
1286 /***************************************************************************
1287  *
1288  *  GIFCOMPR.C       - GIF Image compression routines
1289  *
1290  *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
1291  *  David Rowley (mgardi@watdcsu.waterloo.edu)
1292  *
1293  ***************************************************************************/
1294 
1295 /* General DEFINEs */
1296 
1297 #define GIFBITS	12
1298 
1299 #ifdef NO_UCHAR
1300 typedef char char_type;
1301 #else /* NO_UCHAR */
1302 typedef unsigned char char_type;
1303 #endif /* NO_UCHAR */
1304 
1305 /*
1306  *
1307  * GIF Image compression - modified 'compress'
1308  *
1309  * Based on: compress.c - File compression ala IEEE Computer, June 1984.
1310  *
1311  * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
1312  *              Jim McKie               (decvax!mcvax!jim)
1313  *              Steve Davies            (decvax!vax135!petsd!peora!srd)
1314  *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
1315  *              James A. Woods          (decvax!ihnp4!ames!jaw)
1316  *              Joe Orost               (decvax!vax135!petsd!joe)
1317  *
1318  */
1319 #include <ctype.h>
1320 
1321 #define ARGVAL() (*++(*argv) || (--argc && *++argv))
1322 
1323 #ifdef COMPATIBLE /* But wrong! */
1324 #	define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)
1325 #else /* COMPATIBLE */
1326 #	define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
1327 #endif /* COMPATIBLE */
1328 
1329 #define HashTabOf(i) ctx->htab[i]
1330 #define CodeTabOf(i) ctx->codetab[i]
1331 
1332 
1333 /*
1334  * To save much memory, we overlay the table used by compress() with those
1335  * used by decompress().  The tab_prefix table is the same size and type
1336  * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We
1337  * get this from the beginning of htab.  The output stack uses the rest
1338  * of htab, and contains characters.  There is plenty of room for any
1339  * possible stack (stack used to be 8000 characters).
1340  */
1341 
1342 #define tab_prefixof(i) CodeTabOf(i)
1343 #define tab_suffixof(i) ((char_type*)(htab))[i]
1344 #define de_stack ((char_type*)&tab_suffixof((code_int)1 << GIFBITS))
1345 
1346 /*
1347  * compress stdin to stdout
1348  *
1349  * Algorithm:  use open addressing double hashing (no chaining) on the
1350  * prefix code / next character combination.  We do a variant of Knuth's
1351  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
1352  * secondary probe.  Here, the modular division first probe is gives way
1353  * to a faster exclusive-or manipulation.  Also do block compression with
1354  * an adaptive reset, whereby the code table is cleared when the compression
1355  * ratio decreases, but after the table fills.  The variable-length output
1356  * codes are re-sized at this point, and a special CLEAR code is generated
1357  * for the decompressor.  Late addition:  construct the table according to
1358  * file size for noticeable speed improvement on small files.  Please direct
1359  * questions about this implementation to ames!jaw.
1360  */
1361 
1362 static void output(code_int code, GifCtx *ctx);
1363 
compress(int init_bits,gdIOCtxPtr outfile,gdImagePtr im,GifCtx * ctx)1364 static void compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx)
1365 {
1366 	register long fcode;
1367 	register code_int i;
1368 	register int c;
1369 	register code_int ent;
1370 	register code_int disp;
1371 	register code_int hsize_reg;
1372 	register int hshift;
1373 
1374 	/* Set up the globals:
1375 	 *	g_init_bits - initial number of bits
1376 	 *	g_outfile   - pointer to output file */
1377 	ctx->g_init_bits = init_bits;
1378 	ctx->g_outfile = outfile;
1379 
1380 	/* Set up the necessary values */
1381 	ctx->offset = 0;
1382 	ctx->out_count = 0;
1383 	ctx->clear_flg = 0;
1384 	ctx->in_count = 1;
1385 	ctx->maxcode = MAXCODE(ctx->n_bits = ctx->g_init_bits);
1386 
1387 	ctx->ClearCode = (1 << (init_bits - 1));
1388 	ctx->EOFCode = ctx->ClearCode + 1;
1389 	ctx->free_ent = ctx->ClearCode + 2;
1390 
1391 	char_init(ctx);
1392 
1393 	ent = GIFNextPixel(im, ctx);
1394 
1395 	hshift = 0;
1396 	for(fcode = (long)hsize; fcode < 65536L; fcode *= 2L) {
1397 		++hshift;
1398 	}
1399 	hshift = 8 - hshift; /* set hash code range bound */
1400 
1401 	hsize_reg = hsize;
1402 	cl_hash((count_int) hsize_reg, ctx); /* clear hash table */
1403 
1404 	output((code_int)ctx->ClearCode, ctx);
1405 
1406 #ifdef SIGNED_COMPARE_SLOW
1407 	while((c = GIFNextPixel(im, ctx)) != (unsigned) EOF) {
1408 #else /* SIGNED_COMPARE_SLOW */
1409 	while((c = GIFNextPixel(im, ctx)) != EOF) {
1410 #endif /* SIGNED_COMPARE_SLOW */
1411 
1412 		++(ctx->in_count);
1413 
1414 		fcode = (long) (((long) c << maxbits) + ent);
1415 		i = (((code_int)c << hshift) ^ ent); /* xor hashing */
1416 
1417 		if(HashTabOf(i) == fcode) {
1418 			ent = CodeTabOf (i);
1419 			continue;
1420 		} else if ((long)HashTabOf (i) < 0) {/* empty slot */
1421 			goto nomatch;
1422 		}
1423 
1424 		disp = hsize_reg - i; /* secondary hash (after G. Knott) */
1425 
1426 		if(i == 0) {
1427 			disp = 1;
1428 		}
1429 
1430 probe:
1431 		if((i -= disp) < 0) {
1432 			i += hsize_reg;
1433 		}
1434 
1435 		if(HashTabOf(i) == fcode) {
1436 			ent = CodeTabOf (i);
1437 			continue;
1438 		}
1439 
1440 		if((long)HashTabOf(i) > 0) {
1441 			goto probe;
1442 		}
1443 
1444 nomatch:
1445 		output((code_int) ent, ctx);
1446 		++(ctx->out_count);
1447 		ent = c;
1448 #ifdef SIGNED_COMPARE_SLOW
1449 		if((unsigned) ctx->free_ent < (unsigned) maxmaxcode) {
1450 #else /*SIGNED_COMPARE_SLOW*/
1451 		if (ctx->free_ent < maxmaxcode) {  /* } */
1452 #endif /*SIGNED_COMPARE_SLOW*/
1453 			CodeTabOf(i) = ctx->free_ent++; /* code -> hashtable */
1454 			HashTabOf(i) = fcode;
1455 		} else {
1456 			cl_block(ctx);
1457 		}
1458 	}
1459 
1460 	/* Put out the final code. */
1461 	output((code_int)ent, ctx);
1462 	++(ctx->out_count);
1463 	output((code_int) ctx->EOFCode, ctx);
1464 }
1465 
1466 /*****************************************************************
1467  * TAG( output )
1468  *
1469  * Output the given code.
1470  * Inputs:
1471  *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
1472  *              that n_bits =< (long)wordsize - 1.
1473  * Outputs:
1474  *      Outputs code to the file.
1475  * Assumptions:
1476  *      Chars are 8 bits long.
1477  * Algorithm:
1478  *      Maintain a GIFBITS character long buffer (so that 8 codes will
1479  * fit in it exactly).  Use the VAX insv instruction to insert each
1480  * code in turn.  When the buffer fills up empty it and start over.
1481  */
1482 
1483 static const unsigned long masks[] = {
1484 	0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
1485 	0x001F, 0x003F, 0x007F, 0x00FF,
1486 	0x01FF, 0x03FF, 0x07FF, 0x0FFF,
1487 	0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
1488 };
1489 
1490 /* Arbitrary value to mark output is done.  When we see EOFCode, then we don't
1491  * expect to see any more data.  If we do (e.g. corrupt image inputs), cur_bits
1492  * might be negative, so flag it to return early.
1493  */
1494 #define CUR_BITS_FINISHED -1000
1495 
1496 static void output(code_int code, GifCtx *ctx)
1497 {
1498 	if (ctx->cur_bits == CUR_BITS_FINISHED)
1499 		return;
1500 	ctx->cur_accum &= masks[ctx->cur_bits];
1501 
1502 	if(ctx->cur_bits > 0) {
1503 		ctx->cur_accum |= ((long)code << ctx->cur_bits);
1504 	} else {
1505 		ctx->cur_accum = code;
1506 	}
1507 
1508 	ctx->cur_bits += ctx->n_bits;
1509 
1510 	while(ctx->cur_bits >= 8) {
1511 		char_out((unsigned int)(ctx->cur_accum & 0xff), ctx);
1512 		ctx->cur_accum >>= 8;
1513 		ctx->cur_bits -= 8;
1514 	}
1515 
1516 	/*
1517 	 * If the next entry is going to be too big for the code size,
1518 	 * then increase it, if possible.
1519 	 */
1520 	if(ctx->free_ent > ctx->maxcode || ctx->clear_flg) {
1521 		if(ctx->clear_flg) {
1522 			ctx->maxcode = MAXCODE (ctx->n_bits = ctx->g_init_bits);
1523 			ctx->clear_flg = 0;
1524 		} else {
1525 			++(ctx->n_bits);
1526 			if(ctx->n_bits == maxbits) {
1527 				ctx->maxcode = maxmaxcode;
1528 			} else {
1529 				ctx->maxcode = MAXCODE(ctx->n_bits);
1530 			}
1531 		}
1532 	}
1533 
1534 	if(code == ctx->EOFCode) {
1535 		/* At EOF, write the rest of the buffer. */
1536 		while(ctx->cur_bits > 0) {
1537 			char_out((unsigned int)(ctx->cur_accum & 0xff), ctx);
1538 			ctx->cur_accum >>= 8;
1539 			ctx->cur_bits -= 8;
1540 		}
1541 		/* Flag that it's done to prevent re-entry. */
1542 		ctx->cur_bits = CUR_BITS_FINISHED;
1543 
1544 		flush_char(ctx);
1545 	}
1546 }
1547 
1548 /*
1549  * Clear out the hash table
1550  */
1551 static void cl_block (GifCtx *ctx) /* table clear for block compress */
1552 {
1553 	cl_hash((count_int) hsize, ctx);
1554 	ctx->free_ent = ctx->ClearCode + 2;
1555 	ctx->clear_flg = 1;
1556 
1557 	output((code_int)ctx->ClearCode, ctx);
1558 }
1559 
1560 static void cl_hash(register count_int chsize, GifCtx *ctx) /* reset code table */
1561 {
1562 	register count_int *htab_p = ctx->htab+chsize;
1563 	register long i;
1564 	register long m1 = -1;
1565 
1566 	i = chsize - 16;
1567 	do { /* might use Sys V memset(3) here */
1568 		*(htab_p - 16) = m1;
1569 		*(htab_p - 15) = m1;
1570 		*(htab_p - 14) = m1;
1571 		*(htab_p - 13) = m1;
1572 		*(htab_p - 12) = m1;
1573 		*(htab_p - 11) = m1;
1574 		*(htab_p - 10) = m1;
1575 		*(htab_p - 9) = m1;
1576 		*(htab_p - 8) = m1;
1577 		*(htab_p - 7) = m1;
1578 		*(htab_p - 6) = m1;
1579 		*(htab_p - 5) = m1;
1580 		*(htab_p - 4) = m1;
1581 		*(htab_p - 3) = m1;
1582 		*(htab_p - 2) = m1;
1583 		*(htab_p - 1) = m1;
1584 		htab_p -= 16;
1585 	} while((i -= 16) >= 0);
1586 
1587 	for(i += 16; i > 0; --i) {
1588 		*--htab_p = m1;
1589 	}
1590 }
1591 
1592 /******************************************************************************
1593  *
1594  * GIF Specific routines
1595  *
1596  ******************************************************************************/
1597 
1598 /*
1599  * Set up the 'byte output' routine
1600  */
1601 static void char_init(GifCtx *ctx)
1602 {
1603 	ctx->a_count = 0;
1604 }
1605 
1606 /*
1607  * Add a character to the end of the current packet, and if it is 254
1608  * characters, flush the packet to disk.
1609  */
1610 static void char_out(int c, GifCtx *ctx)
1611 {
1612 	ctx->accum[ctx->a_count++] = c;
1613 	if(ctx->a_count >= 254) {
1614 		flush_char(ctx);
1615 	}
1616 }
1617 
1618 /*
1619  * Flush the packet to disk, and reset the accumulator
1620  */
1621 static void flush_char(GifCtx *ctx)
1622 {
1623 	if(ctx->a_count > 0) {
1624 		gdPutC(ctx->a_count, ctx->g_outfile);
1625 		gdPutBuf(ctx->accum, ctx->a_count, ctx->g_outfile);
1626 		ctx->a_count = 0;
1627 	}
1628 }
1629 
1630 static int gifPutWord(int w, gdIOCtx *out)
1631 {
1632 	/* Byte order is little-endian */
1633 	gdPutC(w & 0xFF, out);
1634 	gdPutC((w >> 8) & 0xFF, out);
1635 	return 0;
1636 }
1637