]> git.pld-linux.org Git - packages/gd.git/blame - gd-gif.patch
- based on patch_gd2.0.15_gif_030801.gz, manually updated for 2.0.17
[packages/gd.git] / gd-gif.patch
Content-type: text/html ]> git.pld-linux.org Git - packages/gd.git/blame - gd-gif.patch


500 - Internal Server Error

Malformed UTF-8 character (fatal) at (eval 6) line 1, <$fd> line 5929.
This page took 0.56244 seconds and 4 git commands to generate.
CommitLineData
68381d70
JB
1diff -Nur gd-2.0.17.orig/gd2togif.c gd-2.0.17/gd2togif.c
2--- gd-2.0.17.orig/gd2togif.c 1970-01-01 01:00:00.000000000 +0100
3+++ gd-2.0.17/gd2togif.c 2003-12-26 15:35:52.279572344 +0100
bd13356b
JB
4@@ -0,0 +1,40 @@
5+#include <stdio.h>
6+#include "gd.h"
7+
8+/* A short program which converts a .gif file into a .gd file, for
9+ your convenience in creating images on the fly from a
10+ basis image that must be loaded quickly. The .gd format
11+ is not intended to be a general-purpose format. */
12+
13+int main(int argc, char **argv)
14+{
15+ gdImagePtr im;
16+ FILE *in, *out;
17+ if (argc != 3) {
18+ fprintf(stderr, "Usage: gd2togif filename.gd2 filename.gif\n");
19+ exit(1);
20+ }
21+ in = fopen(argv[1], "rb");
22+ if (!in) {
23+ fprintf(stderr, "Input file does not exist!\n");
24+ exit(1);
25+ }
26+ im = gdImageCreateFromGd2(in);
27+ fclose(in);
28+ if (!im) {
29+ fprintf(stderr, "Input is not in GIF format!\n");
30+ exit(1);
31+ }
32+ out = fopen(argv[2], "wb");
33+ if (!out) {
34+ fprintf(stderr, "Output file cannot be written to!\n");
35+ gdImageDestroy(im);
36+ exit(1);
37+ }
38+ gdImageGif(im, out);
39+ fclose(out);
40+ gdImageDestroy(im);
41+
42+ return 0;
43+}
44+
68381d70
JB
45diff -Nur gd-2.0.17.orig/gd_biggif_out.c gd-2.0.17/gd_biggif_out.c
46--- gd-2.0.17.orig/gd_biggif_out.c 1970-01-01 01:00:00.000000000 +0100
47+++ gd-2.0.17/gd_biggif_out.c 2003-12-26 15:35:52.285571432 +0100
bd13356b
JB
48@@ -0,0 +1,823 @@
49+#include <stdio.h>
50+#include <math.h>
51+#include <string.h>
52+#include <stdlib.h>
53+#include "gd.h"
54+
55+/*
56+** Wrapper functions for this module.
57+*/
58+
59+void gdImageBigGif(gdImagePtr im, FILE *outFile)
60+{
61+ gdIOCtx *out = gdNewFileCtx(outFile);
62+ gdImageBigGifCtx(im, out);
63+ out->gd_free(out);
64+}
65+
66+void* gdImageBigGifPtr(gdImagePtr im, int *size)
67+{
68+ void *rv;
69+ gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
70+ gdImageBigGifCtx(im, out);
71+ rv = gdDPExtractData(out,size);
72+ out->gd_free(out);
73+ return rv;
74+}
75+
76+/* Code drawn from ppmtogif.c, from the pbmplus package
77+**
78+** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
79+** Lempel-Zim compression based on "compress".
80+**
81+** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
82+**
83+** Copyright (C) 1989 by Jef Poskanzer.
84+**
85+** Permission to use, copy, modify, and distribute this software and its
86+** documentation for any purpose and without fee is hereby granted, provided
87+** that the above copyright notice appear in all copies and that both that
88+** copyright notice and this permission notice appear in supporting
89+** documentation. This software is provided "as is" without express or
90+** implied warranty.
91+**
92+** The Graphics Interchange Format(c) is the Copyright property of
93+** CompuServe Incorporated. GIF(sm) is a Service Mark property of
94+** CompuServe Incorporated.
95+*
96+* Heavily modified by Mouse, 1998-02-12.
97+* Remove LZW compression.
98+* Added miGIF run length compression.
99+*
100+*/
101+
102+/*
103+ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
104+ */
105+typedef int code_int;
106+
107+static int colorstobpp(int colors);
108+static void BumpPixel (void);
109+static int GIFNextPixel (gdImagePtr im);
110+static void GIFEncode (gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
111+/*static void Putword (int w, gdIOCtx *fp); */
112+static void GIFcompress (int, gdIOCtx *, gdImagePtr, int);
113+static void output (code_int code);
114+
115+/* UNUSED
116+* static void char_init (void);
117+* static void char_out (int c);
118+*/
119+
120+/* Allows for reuse */
121+static void init_statics(void);
122+
123+void gdImageBigGifCtx(gdImagePtr im, gdIOCtx *out)
124+{
125+ int interlace, transparent, BitsPerPixel;
126+
127+ interlace = im->interlace;
128+ transparent = im->transparent;
129+
130+ BitsPerPixel = colorstobpp(im->colorsTotal);
131+ /* Clear any old values in statics strewn through the GIF code */
132+ init_statics();
133+ /* All set, let's do it. */
134+ GIFEncode(
135+ out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
136+ im->red, im->green, im->blue, im);
137+}
138+
139+static int
140+colorstobpp(int colors)
141+{
142+ int bpp = 0;
143+
144+ if ( colors <= 2 )
145+ bpp = 1;
146+ else if ( colors <= 4 )
147+ bpp = 2;
148+ else if ( colors <= 8 )
149+ bpp = 3;
150+ else if ( colors <= 16 )
151+ bpp = 4;
152+ else if ( colors <= 32 )
153+ bpp = 5;
154+ else if ( colors <= 64 )
155+ bpp = 6;
156+ else if ( colors <= 128 )
157+ bpp = 7;
158+ else if ( colors <= 256 )
159+ bpp = 8;
160+ return bpp;
161+ }
162+
163+/*****************************************************************************
164+ *
165+ * GIFENCODE.C - GIF Image compression interface
166+ *
167+ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
168+ * BitsPerPixel, Red, Green, Blue, gdImagePtr )
169+ *
170+ *****************************************************************************/
171+
172+#define TRUE 1
173+#define FALSE 0
174+
175+static int Width, Height;
176+static int curx, cury;
177+static long CountDown;
178+static int Pass = 0;
179+static int Interlace;
180+
181+/*
182+ * Bump the 'curx' and 'cury' to point to the next pixel
183+ */
184+static void
185+BumpPixel(void)
186+{
187+ /*
188+ * Bump the current X position
189+ */
190+ ++curx;
191+
192+ /*
193+ * If we are at the end of a scan line, set curx back to the beginning
194+ * If we are interlaced, bump the cury to the appropriate spot,
195+ * otherwise, just increment it.
196+ */
197+ if( curx == Width ) {
198+ curx = 0;
199+
200+ if( !Interlace )
201+ ++cury;
202+ else {
203+ switch( Pass ) {
204+
205+ case 0:
206+ cury += 8;
207+ if( cury >= Height ) {
208+ ++Pass;
209+ cury = 4;
210+ }
211+ break;
212+
213+ case 1:
214+ cury += 8;
215+ if( cury >= Height ) {
216+ ++Pass;
217+ cury = 2;
218+ }
219+ break;
220+
221+ case 2:
222+ cury += 4;
223+ if( cury >= Height ) {
224+ ++Pass;
225+ cury = 1;
226+ }
227+ break;
228+
229+ case 3:
230+ cury += 2;
231+ break;
232+ }
233+ }
234+ }
235+}
236+
237+/*
238+ * Return the next pixel from the image
239+ */
240+static int
241+GIFNextPixel(gdImagePtr im)
242+{
243+ int r;
244+
245+ if( CountDown == 0 )
246+ return EOF;
247+
248+ --CountDown;
249+
250+ r = gdImageGetPixel(im, curx, cury);
251+
252+ BumpPixel();
253+
254+ return r;
255+}
256+
257+/* public */
258+
259+static void
260+GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
261+{
262+ int B;
263+ int RWidth, RHeight;
264+ int LeftOfs, TopOfs;
265+ int Resolution;
266+ int ColorMapSize;
267+ int InitCodeSize;
268+ int i;
269+
270+ Interlace = GInterlace;
271+
272+ ColorMapSize = 1 << BitsPerPixel;
273+
274+ RWidth = Width = GWidth;
275+ RHeight = Height = GHeight;
276+ LeftOfs = TopOfs = 0;
277+
278+ Resolution = BitsPerPixel;
279+
280+ /*
281+ * Calculate number of bits we are expecting
282+ */
283+ CountDown = (long)Width * (long)Height;
284+
285+ /*
286+ * Indicate which pass we are on (if interlace)
287+ */
288+ Pass = 0;
289+
290+ /*
291+ * The initial code size
292+ */
293+ if( BitsPerPixel <= 1 )
294+ InitCodeSize = 2;
295+ else
296+ InitCodeSize = BitsPerPixel;
297+
298+ /*
299+ * Set up the current x and y position
300+ */
301+ curx = cury = 0;
302+
303+ /*
304+ * Write the Magic header
305+ */
306+ gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
307+
308+ /*
309+ * Write out the screen width and height
310+ */
311+ Putword( RWidth, fp );
312+ Putword( RHeight, fp );
313+
314+ /*
315+ * Indicate that there is a global colour map
316+ */
317+ B = 0x80; /* Yes, there is a color map */
318+
319+ /*
320+ * OR in the resolution
321+ */
322+ B |= (Resolution - 1) << 4;
323+
324+ /*
325+ * OR in the Bits per Pixel
326+ */
327+ B |= (BitsPerPixel - 1);
328+
329+ /*
330+ * Write it out
331+ */
332+ gdPutC( B, fp );
333+
334+ /*
335+ * Write out the Background colour
336+ */
337+ gdPutC( Background, fp );
338+
339+ /*
340+ * Byte of 0's (future expansion)
341+ */
342+ gdPutC( 0, fp );
343+
344+ /*
345+ * Write out the Global Colour Map
346+ */
347+ for( i=0; i<ColorMapSize; ++i ) {
348+ gdPutC( Red[i], fp );
349+ gdPutC( Green[i], fp );
350+ gdPutC( Blue[i], fp );
351+ }
352+
353+ /*
354+ * Write out extension for transparent colour index, if necessary.
355+ */
356+ if ( Transparent >= 0 ) {
357+ gdPutC( '!', fp );
358+ gdPutC( 0xf9, fp );
359+ gdPutC( 4, fp );
360+ gdPutC( 1, fp );
361+ gdPutC( 0, fp );
362+ gdPutC( 0, fp );
363+ gdPutC( (unsigned char) Transparent, fp );
364+ gdPutC( 0, fp );
365+ }
366+
367+ /*
368+ * Write an Image separator
369+ */
370+ gdPutC( ',', fp );
371+
372+ /*
373+ * Write the Image header
374+ */
375+
376+ Putword( LeftOfs, fp );
377+ Putword( TopOfs, fp );
378+ Putword( Width, fp );
379+ Putword( Height, fp );
380+
381+ /*
382+ * Write out whether or not the image is interlaced
383+ */
384+ if( Interlace )
385+ gdPutC( 0x40, fp );
386+ else
387+ gdPutC( 0x00, fp );
388+
389+ /*
390+ * Write out the initial code size
391+ */
392+ gdPutC( InitCodeSize, fp );
393+
394+ /*
395+ * Go and actually compress the data
396+ */
397+ GIFcompress( InitCodeSize+1, fp, im, Background );
398+
399+ /*
400+ * Write out a Zero-length packet (to end the series)
401+ */
402+ gdPutC( 0, fp );
403+
404+ /*
405+ * Write the GIF file terminator
406+ */
407+ gdPutC( ';', fp );
408+}
409+
410+/* Write out a word to the GIF file */
411+/*static void */
412+/*Putword(int w, gdIOCtx *fp) */
413+/*{ */
414+/* fputc( w & 0xff, fp ); */
415+/* fputc( (w / 256) & 0xff, fp ); */
416+/*} */
417+
418+#define GIFBITS 12
419+
420+/*-----------------------------------------------------------------------
421+ *
422+ * miGIF Compression - mouse and ivo's GIF-compatible compression
423+ *
424+ * -run length encoding compression routines-
425+ *
426+ * Copyright (C) 1998 Hutchison Avenue Software Corporation
427+ * http://www.hasc.com
428+ * info@hasc.com
429+ *
430+ * Permission to use, copy, modify, and distribute this software and its
431+ * documentation for any purpose and without fee is hereby granted, provided
432+ * that the above copyright notice appear in all copies and that both that
433+ * copyright notice and this permission notice appear in supporting
434+ * documentation. This software is provided "AS IS." The Hutchison Avenue
435+ * Software Corporation disclaims all warranties, either express or implied,
436+ * including but not limited to implied warranties of merchantability and
437+ * fitness for a particular purpose, with respect to this code and accompanying
438+ * documentation.
439+ *
440+ * The miGIF compression routines do not, strictly speaking, generate files
441+ * conforming to the GIF spec, since the image data is not LZW-compressed
442+ * (this is the point: in order to avoid transgression of the Unisys patent
443+ * on the LZW algorithm.) However, miGIF generates data streams that any
444+ * reasonably sane LZW decompresser will decompress to what we want.
445+ *
446+ * miGIF compression uses run length encoding. It compresses horizontal runs
447+ * of pixels of the same color. This type of compression gives good results
448+ * on images with many runs, for example images with lines, text and solid
449+ * shapes on a solid-colored background. It gives little or no compression
450+ * on images with few runs, for example digital or scanned photos.
451+ *
452+ * der Mouse
453+ * mouse@rodents.montreal.qc.ca
454+ * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
455+ *
456+ * ivo@hasc.com
457+ *
458+ * The Graphics Interchange Format(c) is the Copyright property of
459+ * CompuServe Incorporated. GIF(sm) is a Service Mark property of
460+ * CompuServe Incorporated.
461+ *
462+ */
463+
464+static int rl_pixel;
465+static int rl_basecode;
466+static int rl_count;
467+static int rl_table_pixel;
468+static int rl_table_max;
469+static int just_cleared;
470+static int out_bits;
471+static int out_bits_init;
472+static int out_count;
473+static int out_bump;
474+static int out_bump_init;
475+static int out_clear;
476+static int out_clear_init;
477+static int max_ocodes;
478+static int code_clear;
479+static int code_eof;
480+static unsigned int obuf;
481+static int obits;
482+static gdIOCtx *ofile;
483+static unsigned char oblock[256];
484+static int oblen;
485+
486+/* Used only when debugging GIF compression code */
487+/* #define DEBUGGING_ENVARS */
488+
489+#ifdef DEBUGGING_ENVARS
490+
491+static int verbose_set = 0;
492+static int verbose;
493+#define VERBOSE (verbose_set?verbose:set_verbose())
494+
495+static int set_verbose(void)
496+{
497+ verbose = !!getenv("GIF_VERBOSE");
498+ verbose_set = 1;
499+ return(verbose);
500+}
501+
502+#else
503+
504+#define VERBOSE 0
505+
506+#endif
507+
508+
509+static const char *binformat(unsigned int v, int nbits)
510+{
511+ static char bufs[8][64];
512+ static int bhand = 0;
513+ unsigned int bit;
514+ int bno;
515+ char *bp;
516+
517+ bhand --;
518+ if (bhand < 0) bhand = (sizeof(bufs)/sizeof(bufs[0]))-1;
519+ bp = &bufs[bhand][0];
520+ for (bno=nbits-1,bit=1U<<bno;bno>=0;bno--,bit>>=1)
521+ { *bp++ = (v & bit) ? '1' : '0';
522+ if (((bno&3) == 0) && (bno != 0)) *bp++ = '.';
523+ }
524+ *bp = '\0';
525+ return(&bufs[bhand][0]);
526+}
527+
528+static void write_block(void)
529+{
530+ int i;
531+
532+ if (VERBOSE)
533+ { printf("write_block %d:",oblen);
534+ for (i=0;i<oblen;i++) printf(" %02x",oblock[i]);
535+ printf("\n");
536+ }
537+ gdPutC(oblen,ofile);
538+ gdPutBuf(&oblock[0],oblen,ofile);
539+ oblen = 0;
540+}
541+
542+static void block_out(unsigned char c)
543+{
544+ if (VERBOSE) printf("block_out %s\n",binformat(c,8));
545+ oblock[oblen++] = c;
546+ if (oblen >= 255) write_block();
547+}
548+
549+static void block_flush(void)
550+{
551+ if (VERBOSE) printf("block_flush\n");
552+ if (oblen > 0) write_block();
553+}
554+
555+static void output(int val)
556+{
557+ if (VERBOSE) printf("output %s [%s %d %d]\n",binformat(val,out_bits),binformat(obuf,obits),obits,out_bits);
558+ obuf |= val << obits;
559+ obits += out_bits;
560+ while (obits >= 8)
561+ { block_out(obuf&0xff);
562+ obuf >>= 8;
563+ obits -= 8;
564+ }
565+ if (VERBOSE) printf("output leaving [%s %d]\n",binformat(obuf,obits),obits);
566+}
567+
568+static void output_flush(void)
569+{
570+ if (VERBOSE) printf("output_flush\n");
571+ if (obits > 0) block_out(obuf);
572+ block_flush();
573+}
574+
575+static void did_clear(void)
576+{
577+ if (VERBOSE) printf("did_clear\n");
578+ out_bits = out_bits_init;
579+ out_bump = out_bump_init;
580+ out_clear = out_clear_init;
581+ out_count = 0;
582+ rl_table_max = 0;
583+ just_cleared = 1;
584+}
585+
586+static void output_plain(int c)
587+{
588+ if (VERBOSE) printf("output_plain %s\n",binformat(c,out_bits));
589+ just_cleared = 0;
590+ output(c);
591+ out_count ++;
592+ if (out_count >= out_bump)
593+ { out_bits ++;
594+ out_bump += 1 << (out_bits - 1);
595+ }
596+ if (out_count >= out_clear)
597+ { output(code_clear);
598+ did_clear();
599+ }
600+}
601+
602+static unsigned int isqrt(unsigned int x)
603+{
604+ unsigned int r;
605+ unsigned int v;
606+
607+ if (x < 2) return(x);
608+ for (v=x,r=1;v;v>>=2,r<<=1) ;
609+ while (1)
610+ { v = ((x / r) + r) / 2;
611+ if ((v == r) || (v == r+1)) return(r);
612+ r = v;
613+ }
614+}
615+
616+static unsigned int compute_triangle_count(unsigned int count, unsigned int nrepcodes)
617+{
618+ unsigned int perrep;
619+ unsigned int cost;
620+
621+ cost = 0;
622+ perrep = (nrepcodes * (nrepcodes+1)) / 2;
623+ while (count >= perrep)
624+ { cost += nrepcodes;
625+ count -= perrep;
626+ }
627+ if (count > 0)
628+ { unsigned int n;
629+ n = isqrt(count);
630+ while ((n*(n+1)) >= 2*count) n --;
631+ while ((n*(n+1)) < 2*count) n ++;
632+ cost += n;
633+ }
634+ return(cost);
635+}
636+
637+static void max_out_clear(void)
638+{
639+ out_clear = max_ocodes;
640+}
641+
642+static void reset_out_clear(void)
643+{
644+ out_clear = out_clear_init;
645+ if (out_count >= out_clear)
646+ { output(code_clear);
647+ did_clear();
648+ }
649+}
650+
651+static void rl_flush_fromclear(int count)
652+{
653+ int n;
654+
655+ if (VERBOSE) printf("rl_flush_fromclear %d\n",count);
656+ max_out_clear();
657+ rl_table_pixel = rl_pixel;
658+ n = 1;
659+ while (count > 0)
660+ { if (n == 1)
661+ { rl_table_max = 1;
662+ output_plain(rl_pixel);
663+ count --;
664+ }
665+ else if (count >= n)
666+ { rl_table_max = n;
667+ output_plain(rl_basecode+n-2);
668+ count -= n;
669+ }
670+ else if (count == 1)
671+ { rl_table_max ++;
672+ output_plain(rl_pixel);
673+ count = 0;
674+ }
675+ else
676+ { rl_table_max ++;
677+ output_plain(rl_basecode+count-2);
678+ count = 0;
679+ }
680+ if (out_count == 0) n = 1; else n ++;
681+ }
682+ reset_out_clear();
683+ if (VERBOSE) printf("rl_flush_fromclear leaving table_max=%d\n",rl_table_max);
684+}
685+
686+static void rl_flush_clearorrep(int count)
687+{
688+ int withclr;
689+
690+ if (VERBOSE) printf("rl_flush_clearorrep %d\n",count);
691+ withclr = 1 + compute_triangle_count(count,max_ocodes);
692+ if (withclr < count)
693+ { output(code_clear);
694+ did_clear();
695+ rl_flush_fromclear(count);
696+ }
697+ else
698+ { for (;count>0;count--) output_plain(rl_pixel);
699+ }
700+}
701+
702+static void rl_flush_withtable(int count)
703+{
704+ int repmax;
705+ int repleft;
706+ int leftover;
707+
708+ if (VERBOSE) printf("rl_flush_withtable %d\n",count);
709+ repmax = count / rl_table_max;
710+ leftover = count % rl_table_max;
711+ repleft = (leftover ? 1 : 0);
712+ if (out_count+repmax+repleft > max_ocodes)
713+ { repmax = max_ocodes - out_count;
714+ leftover = count - (repmax * rl_table_max);
715+ repleft = 1 + compute_triangle_count(leftover,max_ocodes);
716+ }
717+ if (VERBOSE) printf("rl_flush_withtable repmax=%d leftover=%d repleft=%d\n",repmax,leftover,repleft);
718+ if (1+compute_triangle_count(count,max_ocodes) < repmax+repleft)
719+ { output(code_clear);
720+ did_clear();
721+ rl_flush_fromclear(count);
722+ return;
723+ }
724+ max_out_clear();
725+ for (;repmax>0;repmax--) output_plain(rl_basecode+rl_table_max-2);
726+ if (leftover)
727+ { if (just_cleared)
728+ { rl_flush_fromclear(leftover);
729+ }
730+ else if (leftover == 1)
731+ { output_plain(rl_pixel);
732+ }
733+ else
734+ { output_plain(rl_basecode+leftover-2);
735+ }
736+ }
737+ reset_out_clear();
738+}
739+
740+static void rl_flush(void)
741+{
742+ /* UNUSED int table_reps; */
743+ /* UNUSED int table_extra; */
744+
745+ if (VERBOSE) printf("rl_flush [ %d %d\n",rl_count,rl_pixel);
746+ if (rl_count == 1)
747+ { output_plain(rl_pixel);
748+ rl_count = 0;
749+ if (VERBOSE) printf("rl_flush ]\n");
750+ return;
751+ }
752+ if (just_cleared)
753+ { rl_flush_fromclear(rl_count);
754+ }
755+ else if ((rl_table_max < 2) || (rl_table_pixel != rl_pixel))
756+ { rl_flush_clearorrep(rl_count);
757+ }
758+ else
759+ { rl_flush_withtable(rl_count);
760+ }
761+ if (VERBOSE) printf("rl_flush ]\n");
762+ rl_count = 0;
763+}
764+
765+static void GIFcompress(int init_bits, gdIOCtx *outfile, gdImagePtr im, int background)
766+{
767+ int c;
768+
769+ ofile = outfile;
770+ obuf = 0;
771+ obits = 0;
772+ oblen = 0;
773+ code_clear = 1 << (init_bits - 1);
774+ code_eof = code_clear + 1;
775+ rl_basecode = code_eof + 1;
776+ out_bump_init = (1 << (init_bits - 1)) - 1;
777+ /* for images with a lot of runs, making out_clear_init larger will
778+ give better compression. */
779+ out_clear_init = (init_bits <= 3) ? 9 : (out_bump_init-1);
780+#ifdef DEBUGGING_ENVARS
781+ { const char *ocienv;
782+ ocienv = getenv("GIF_OUT_CLEAR_INIT");
783+ if (ocienv)
784+ { out_clear_init = atoi(ocienv);
785+ if (VERBOSE) printf("[overriding out_clear_init to %d]\n",out_clear_init);
786+ }
787+ }
788+#endif
789+ out_bits_init = init_bits;
790+ max_ocodes = (1 << GIFBITS) - ((1 << (out_bits_init - 1)) + 3);
791+ did_clear();
792+ output(code_clear);
793+ rl_count = 0;
794+ while (1)
795+ { c = GIFNextPixel(im);
796+ if ((rl_count > 0) && (c != rl_pixel)) rl_flush();
797+ if (c == EOF) break;
798+ if (rl_pixel == c)
799+ { rl_count ++;
800+ }
801+ else
802+ { rl_pixel = c;
803+ rl_count = 1;
804+ }
805+ }
806+ output(code_eof);
807+ output_flush();
808+}
809+
810+/*-----------------------------------------------------------------------
811+ *
812+ * End of miGIF section - See copyright notice at start of section.
813+ *
814+ *-----------------------------------------------------------------------
815+*/
816+
817+/******************************************************************************
818+ *
819+ * GIF Specific routines
820+ *
821+ ******************************************************************************/
822+
823+/*
824+ * Number of characters so far in this 'packet'
825+ */
826+static int a_count;
827+
828+/*
829+ * Set up the 'byte output' routine
830+ */
831+
832+/* UNUSED
833+* static void
834+* char_init(void)
835+* {
836+* a_count = 0;
837+* }
838+*/
839+
840+/*
841+ * Define the storage for the packet accumulator
842+ */
843+
844+/* UNUSED static char accum[ 256 ]; */
845+
846+static void init_statics(void) {
847+ /* Some of these are properly initialized later. What I'm doing
848+ here is making sure code that depends on C's initialization
849+ of statics doesn't break when the code gets called more
850+ than once. */
851+ Width = 0;
852+ Height = 0;
853+ curx = 0;
854+ cury = 0;
855+ CountDown = 0;
856+ Pass = 0;
857+ Interlace = 0;
858+ a_count = 0;
859+}
860+
861+
862+/* +-------------------------------------------------------------------+ */
863+/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
864+/* | Permission to use, copy, modify, and distribute this software | */
865+/* | and its documentation for any purpose and without fee is hereby | */
866+/* | granted, provided that the above copyright notice appear in all | */
867+/* | copies and that both that copyright notice and this permission | */
868+/* | notice appear in supporting documentation. This software is | */
869+/* | provided "as is" without express or implied warranty. | */
870+/* +-------------------------------------------------------------------+ */
871+
68381d70
JB
872diff -Nur gd-2.0.17.orig/gd.c gd-2.0.17/gd.c
873--- gd-2.0.17.orig/gd.c 2003-12-24 22:43:06.000000000 +0100
874+++ gd-2.0.17/gd.c 2003-12-26 15:35:52.264574624 +0100
875@@ -2695,7 +2695,17 @@
876 }
877
878 void
879-gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
880+gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c)
881+{
882+ if (!n) {
883+ return;
884+ }
885+ gdImageLine(im, p->x, p->y, p[n-1].x, p[n-1].y, c);
886+ gdImageOpenPolygon(im, p, n, c);
887+}
888+
889+void
890+gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
891 {
892 int i;
893 int lx, ly;
894@@ -2711,7 +2721,6 @@
895
896 lx = p->x;
897 ly = p->y;
898- gdImageLine (im, lx, ly, p[n - 1].x, p[n - 1].y, c);
899 for (i = 1; (i < n); i++)
900 {
901 p++;
902diff -Nur gd-2.0.17.orig/gdcmpgif.c gd-2.0.17/gdcmpgif.c
903--- gd-2.0.17.orig/gdcmpgif.c 1970-01-01 01:00:00.000000000 +0100
904+++ gd-2.0.17/gdcmpgif.c 2003-12-26 15:35:52.303568696 +0100
905@@ -0,0 +1,85 @@
906+#include <stdio.h>
907+#include <unistd.h> /* For unlink function */
908+#include "gd.h"
909+
910+/* A short program which converts a .png file into a .gd file, for
911+ your convenience in creating images on the fly from a
912+ basis image that must be loaded quickly. The .gd format
913+ is not intended to be a general-purpose format. */
914+
915+void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2);
916+
917+
918+int main(int argc, char **argv)
919+{
920+ gdImagePtr im1, im2;
921+ FILE *in;
922+
923+ if (argc != 3) {
924+ fprintf(stderr, "Usage: gdcmpgif filename.gif filename.gif\n");
925+ exit(1);
926+ }
927+ in = fopen(argv[1], "rb");
928+ if (!in) {
929+ fprintf(stderr, "Input file does not exist!\n");
930+ exit(1);
931+ }
932+ im1 = gdImageCreateFromGif(in);
933+ fclose(in);
934+
935+ if (!im1) {
936+ fprintf(stderr, "Input is not in GIF format!\n");
937+ exit(1);
938+ }
939+
940+ in = fopen(argv[2], "rb");
941+ if (!in) {
942+ fprintf(stderr, "Input file 2 does not exist!\n");
943+ exit(1);
944+ }
945+ im2 = gdImageCreateFromGif(in);
946+ fclose(in);
947+
948+ if (!im2) {
949+ fprintf(stderr, "Input 2 is not in GIF format!\n");
950+ exit(1);
951+ }
952+
953+ CompareImages("gdcmpgif", im1, im2);
954+
955+ gdImageDestroy(im1);
956+ gdImageDestroy(im2);
957+
958+ return 0;
959+}
960+
961+void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2)
962+{
963+ int cmpRes;
964+
965+ cmpRes = gdImageCompare(im1, im2);
966+
967+ if (cmpRes & GD_CMP_IMAGE) {
968+ printf("%%%s: ERROR images differ: BAD\n",msg);
969+ } else if (cmpRes != 0) {
970+ printf("%%%s: WARNING images differ: WARNING - Probably OK\n",msg);
971+ } else {
972+ printf("%%%s: OK\n",msg);
973+ return;
974+ }
975+
976+ if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) {
977+ printf("-%s: INFO image sizes differ\n",msg);
978+ }
979+
980+ if (cmpRes & GD_CMP_NUM_COLORS) {
981+ printf("-%s: INFO number of pallette entries differ %d Vs. %d\n",msg,
982+ im1->colorsTotal, im2->colorsTotal);
983+ }
984+
985+ if (cmpRes & GD_CMP_COLOR) {
986+ printf("-%s: INFO actual colours of pixels differ\n",msg);
987+ }
988+}
989+
990+
991diff -Nur gd-2.0.17.orig/gd_gif_in.c gd-2.0.17/gd_gif_in.c
992--- gd-2.0.17.orig/gd_gif_in.c 1970-01-01 01:00:00.000000000 +0100
993+++ gd-2.0.17/gd_gif_in.c 2003-12-26 15:35:52.291570520 +0100
bd13356b
JB
994@@ -0,0 +1,573 @@
995+#include <stdio.h>
996+#include <math.h>
997+#include <string.h>
998+#include <stdlib.h>
999+#include "gd.h"
1000+
1001+/* Used only when debugging GIF compression code */
1002+/* #define DEBUGGING_ENVARS */
1003+
1004+#ifdef DEBUGGING_ENVARS
1005+
1006+static int verbose_set = 0;
1007+static int verbose;
1008+#define VERBOSE (verbose_set?verbose:set_verbose())
1009+
1010+static int set_verbose(void)
1011+{
1012+ verbose = !!getenv("GIF_VERBOSE");
1013+ verbose_set = 1;
1014+ return(verbose);
1015+}
1016+
1017+#else
1018+
1019+#define VERBOSE 0
1020+
1021+#endif
1022+
1023+
1024+#define MAXCOLORMAPSIZE 256
1025+
1026+#define TRUE 1
1027+#define FALSE 0
1028+
1029+#define CM_RED 0
1030+#define CM_GREEN 1
1031+#define CM_BLUE 2
1032+
1033+#define MAX_LWZ_BITS 12
1034+
1035+#define INTERLACE 0x40
1036+#define LOCALCOLORMAP 0x80
1037+#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
1038+
1039+#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
1040+
1041+#define LM_to_uint(a,b) (((b)<<8)|(a))
1042+
1043+/* We may eventually want to use this information, but def it out for now */
1044+#if 0
1045+static struct {
1046+ unsigned int Width;
1047+ unsigned int Height;
1048+ unsigned char ColorMap[3][MAXCOLORMAPSIZE];
1049+ unsigned int BitPixel;
1050+ unsigned int ColorResolution;
1051+ unsigned int Background;
1052+ unsigned int AspectRatio;
1053+} GifScreen;
1054+#endif
1055+
1056+static struct {
1057+ int transparent;
1058+ int delayTime;
1059+ int inputFlag;
1060+ int disposal;
1061+} Gif89 = { -1, -1, -1, 0 };
1062+
1063+static int ReadColorMap (gdIOCtx *fd, int number, unsigned char (*buffer)[256]);
1064+static int DoExtension (gdIOCtx *fd, int label, int *Transparent);
1065+static int GetDataBlock (gdIOCtx *fd, unsigned char *buf);
1066+static int GetCode (gdIOCtx *fd, int code_size, int flag);
1067+static int LWZReadByte (gdIOCtx *fd, int flag, int input_code_size);
1068+
1069+static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */
1070+
1071+int ZeroDataBlock;
1072+
1073+gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource)
1074+{
1075+ gdIOCtx *in = gdNewSSCtx(inSource, NULL);
1076+ gdImagePtr im;
1077+
1078+ im = gdImageCreateFromGifCtx(in);
1079+
1080+ in->gd_free(in);
1081+
1082+ return im;
1083+}
1084+
1085+gdImagePtr
1086+gdImageCreateFromGif(FILE *fdFile)
1087+{
1088+ gdIOCtx *fd = gdNewFileCtx(fdFile);
1089+ gdImagePtr im = 0;
1090+
1091+ im = gdImageCreateFromGifCtx(fd);
1092+
1093+ fd->gd_free(fd);
1094+
1095+ return im;
1096+}
1097+
1098+gdImagePtr
1099+gdImageCreateFromGifCtx(gdIOCtxPtr fd)
1100+{
1101+/* 1.4 int imageNumber; */
1102+ int BitPixel;
1103+ int ColorResolution;
1104+ int Background;
1105+ int AspectRatio;
1106+ int Transparent = (-1);
1107+ unsigned char buf[16];
1108+ unsigned char c;
1109+ unsigned char ColorMap[3][MAXCOLORMAPSIZE];
1110+ unsigned char localColorMap[3][MAXCOLORMAPSIZE];
1111+ int imw, imh;
1112+ int useGlobalColormap;
1113+ int bitPixel;
1114+ int i;
1115+ /*1.4//int imageCount = 0; */
1116+ char version[4];
1117+
1118+ gdImagePtr im = 0;
1119+ ZeroDataBlock = FALSE;
1120+
1121+ /*1.4//imageNumber = 1; */
1122+ if (! ReadOK(fd,buf,6)) {
1123+ return 0;
1124+ }
1125+ if (strncmp((char *)buf,"GIF",3) != 0) {
1126+ return 0;
1127+ }
1128+ strncpy(version, (char *)buf + 3, 3);
1129+ version[3] = '\0';
1130+
1131+ if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
1132+ return 0;
1133+ }
1134+ if (! ReadOK(fd,buf,7)) {
1135+ return 0;
1136+ }
1137+ BitPixel = 2<<(buf[4]&0x07);
1138+ ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
1139+ Background = buf[5];
1140+ AspectRatio = buf[6];
1141+
1142+ if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
1143+ if (ReadColorMap(fd, BitPixel, ColorMap)) {
1144+ return 0;
1145+ }
1146+ }
1147+ for (;;) {
1148+ if (! ReadOK(fd,&c,1)) {
1149+ return 0;
1150+ }
1151+ if (c == ';') { /* GIF terminator */
1152+ goto terminated;
1153+ }
1154+
1155+ if (c == '!') { /* Extension */
1156+ if (! ReadOK(fd,&c,1)) {
1157+ return 0;
1158+ }
1159+ DoExtension(fd, c, &Transparent);
1160+ continue;
1161+ }
1162+
1163+ if (c != ',') { /* Not a valid start character */
1164+ continue;
1165+ }
1166+
1167+ /*1.4//++imageCount; */
1168+
1169+ if (! ReadOK(fd,buf,9)) {
1170+ return 0;
1171+ }
1172+
1173+ useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
1174+
1175+ bitPixel = 1<<((buf[8]&0x07)+1);
1176+
1177+ imw = LM_to_uint(buf[4],buf[5]);
1178+ imh = LM_to_uint(buf[6],buf[7]);
1179+ if (!(im = gdImageCreate(imw, imh))) {
1180+ return 0;
1181+ }
1182+ im->interlace = BitSet(buf[8], INTERLACE);
1183+ if (! useGlobalColormap) {
1184+ if (ReadColorMap(fd, bitPixel, localColorMap)) {
1185+ return 0;
1186+ }
1187+ ReadImage(im, fd, imw, imh, localColorMap,
1188+ BitSet(buf[8], INTERLACE));
1189+ /*1.4//imageCount != imageNumber); */
1190+ } else {
1191+ ReadImage(im, fd, imw, imh,
1192+ ColorMap,
1193+ BitSet(buf[8], INTERLACE));
1194+ /*1.4//imageCount != imageNumber); */
1195+ }
1196+ if (Transparent != (-1)) {
1197+ gdImageColorTransparent(im, Transparent);
1198+ }
1199+ goto terminated;
1200+ }
1201+
1202+terminated:
1203+ /* Terminator before any image was declared! */
1204+ if (!im) {
1205+ return 0;
1206+ }
1207+ /* Check for open colors at the end, so
1208+ we can reduce colorsTotal and ultimately
1209+ BitsPerPixel */
1210+ for (i=((im->colorsTotal-1)); (i>=0); i--) {
1211+ if (im->open[i]) {
1212+ im->colorsTotal--;
1213+ } else {
1214+ break;
1215+ }
1216+ }
1217+ return im;
1218+}
1219+
1220+static int
1221+ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256])
1222+{
1223+ int i;
1224+ unsigned char rgb[3];
1225+
1226+
1227+ for (i = 0; i < number; ++i) {
1228+ if (! ReadOK(fd, rgb, sizeof(rgb))) {
1229+ return TRUE;
1230+ }
1231+ buffer[CM_RED][i] = rgb[0] ;
1232+ buffer[CM_GREEN][i] = rgb[1] ;
1233+ buffer[CM_BLUE][i] = rgb[2] ;
1234+ }
1235+
1236+
1237+ return FALSE;
1238+}
1239+
1240+static int
1241+DoExtension(gdIOCtx *fd, int label, int *Transparent)
1242+{
1243+ static unsigned char buf[256];
1244+
1245+ switch (label) {
1246+ case 0xf9: /* Graphic Control Extension */
1247+ (void) GetDataBlock(fd, (unsigned char*) buf);
1248+ Gif89.disposal = (buf[0] >> 2) & 0x7;
1249+ Gif89.inputFlag = (buf[0] >> 1) & 0x1;
1250+ Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
1251+ if ((buf[0] & 0x1) != 0)
1252+ *Transparent = buf[3];
1253+
1254+ while (GetDataBlock(fd, (unsigned char*) buf) != 0)
1255+ ;
1256+ return FALSE;
1257+ default:
1258+ break;
1259+ }
1260+ while (GetDataBlock(fd, (unsigned char*) buf) != 0)
1261+ ;
1262+
1263+ return FALSE;
1264+}
1265+
1266+static int
1267+GetDataBlock_(gdIOCtx *fd, unsigned char *buf)
1268+{
1269+ unsigned char count;
1270+
1271+ if (! ReadOK(fd,&count,1)) {
1272+ return -1;
1273+ }
1274+
1275+ ZeroDataBlock = count == 0;
1276+
1277+ if ((count != 0) && (! ReadOK(fd, buf, count))) {
1278+ return -1;
1279+ }
1280+
1281+ return count;
1282+}
1283+
1284+static int
1285+GetDataBlock(gdIOCtx *fd, unsigned char *buf)
1286+{
1287+ int rv;
1288+ int i;
1289+
1290+ rv = GetDataBlock_(fd,buf);
1291+ if (VERBOSE)
1292+ { printf("[GetDataBlock returning %d",rv);
1293+ if (rv > 0)
1294+ { printf(":");
1295+ for (i=0;i<rv;i++) printf(" %02x",buf[i]);
1296+ }
1297+ printf("]\n");
1298+ }
1299+ return(rv);
1300+}
1301+
1302+static int
1303+GetCode_(gdIOCtx *fd, int code_size, int flag)
1304+{
1305+ static unsigned char buf[280];
1306+ static int curbit, lastbit, done, last_byte;
1307+ int i, j, ret;
1308+ unsigned char count;
1309+
1310+ if (flag) {
1311+ curbit = 0;
1312+ lastbit = 0;
1313+ done = FALSE;
1314+ return 0;
1315+ }
1316+
1317+ if ( (curbit+code_size) >= lastbit) {
1318+ if (done) {
1319+ if (curbit >= lastbit) {
1320+ /* Oh well */
1321+ }
1322+ return -1;
1323+ }
1324+ buf[0] = buf[last_byte-2];
1325+ buf[1] = buf[last_byte-1];
1326+
1327+ if ((count = GetDataBlock(fd, &buf[2])) == 0)
1328+ done = TRUE;
1329+
1330+ last_byte = 2 + count;
1331+ curbit = (curbit - lastbit) + 16;
1332+ lastbit = (2+count)*8 ;
1333+ }
1334+
1335+ ret = 0;
1336+ for (i = curbit, j = 0; j < code_size; ++i, ++j)
1337+ ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
1338+
1339+ curbit += code_size;
1340+ return ret;
1341+}
1342+
1343+static int
1344+GetCode(gdIOCtx *fd, int code_size, int flag)
1345+{
1346+ int rv;
1347+
1348+ rv = GetCode_(fd,code_size,flag);
1349+ if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
1350+ return(rv);
1351+}
1352+
1353+#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
1354+static int
1355+LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size)
1356+{
1357+ static int fresh = FALSE;
1358+ int code, incode;
1359+ static int code_size, set_code_size;
1360+ static int max_code, max_code_size;
1361+ static int firstcode, oldcode;
1362+ static int clear_code, end_code;
1363+ static int table[2][(1<< MAX_LWZ_BITS)];
1364+ static int stack[STACK_SIZE], *sp;
1365+ register int i;
1366+
1367+ if (flag) {
1368+ set_code_size = input_code_size;
1369+ code_size = set_code_size+1;
1370+ clear_code = 1 << set_code_size ;
1371+ end_code = clear_code + 1;
1372+ max_code_size = 2*clear_code;
1373+ max_code = clear_code+2;
1374+
1375+ GetCode(fd, 0, TRUE);
1376+
1377+ fresh = TRUE;
1378+
1379+ for (i = 0; i < clear_code; ++i) {
1380+ table[0][i] = 0;
1381+ table[1][i] = i;
1382+ }
1383+ for (; i < (1<<MAX_LWZ_BITS); ++i)
1384+ table[0][i] = table[1][0] = 0;
1385+
1386+ sp = stack;
1387+
1388+ return 0;
1389+ } else if (fresh) {
1390+ fresh = FALSE;
1391+ do {
1392+ firstcode = oldcode =
1393+ GetCode(fd, code_size, FALSE);
1394+ } while (firstcode == clear_code);
1395+ return firstcode;
1396+ }
1397+
1398+ if (sp > stack)
1399+ return *--sp;
1400+
1401+ while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
1402+ if (code == clear_code) {
1403+ for (i = 0; i < clear_code; ++i) {
1404+ table[0][i] = 0;
1405+ table[1][i] = i;
1406+ }
1407+ for (; i < (1<<MAX_LWZ_BITS); ++i)
1408+ table[0][i] = table[1][i] = 0;
1409+ code_size = set_code_size+1;
1410+ max_code_size = 2*clear_code;
1411+ max_code = clear_code+2;
1412+ sp = stack;
1413+ firstcode = oldcode =
1414+ GetCode(fd, code_size, FALSE);
1415+ return firstcode;
1416+ } else if (code == end_code) {
1417+ int count;
1418+ unsigned char buf[260];
1419+
1420+ if (ZeroDataBlock)
1421+ return -2;
1422+
1423+ while ((count = GetDataBlock(fd, buf)) > 0)
1424+ ;
1425+
1426+ if (count != 0)
1427+ return -2;
1428+ }
1429+
1430+ incode = code;
1431+
1432+ if (sp == (stack + STACK_SIZE)) {
1433+ /* Bad compressed data stream */
1434+ return -1;
1435+ }
1436+
1437+ if (code >= max_code) {
1438+ *sp++ = firstcode;
1439+ code = oldcode;
1440+ }
1441+
1442+ while (code >= clear_code) {
1443+ if (sp == (stack + STACK_SIZE)) {
1444+ /* Bad compressed data stream */
1445+ return -1;
1446+ }
1447+ *sp++ = table[1][code];
1448+ if (code == table[0][code]) {
1449+ /* Oh well */
1450+ }
1451+ code = table[0][code];
1452+ }
1453+
1454+ *sp++ = firstcode = table[1][code];
1455+
1456+ if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
1457+ table[0][code] = oldcode;
1458+ table[1][code] = firstcode;
1459+ ++max_code;
1460+ if ((max_code >= max_code_size) &&
1461+ (max_code_size < (1<<MAX_LWZ_BITS))) {
1462+ max_code_size *= 2;
1463+ ++code_size;
1464+ }
1465+ }
1466+
1467+ oldcode = incode;
1468+
1469+ if (sp > stack)
1470+ return *--sp;
1471+ }
1472+ return code;
1473+}
1474+
1475+static int
1476+LWZReadByte(gdIOCtx *fd, int flag, int input_code_size)
1477+{
1478+ int rv;
1479+
1480+ rv = LWZReadByte_(fd,flag,input_code_size);
1481+ if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
1482+ return(rv);
1483+}
1484+
1485+static void
1486+ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */
1487+{
1488+ unsigned char c;
1489+ int v;
1490+ int xpos = 0, ypos = 0, pass = 0;
1491+ int i;
1492+ /* Stash the color map into the image */
1493+ for (i=0; (i<gdMaxColors); i++) {
1494+ im->red[i] = cmap[CM_RED][i];
1495+ im->green[i] = cmap[CM_GREEN][i];
1496+ im->blue[i] = cmap[CM_BLUE][i];
1497+ im->open[i] = 1;
1498+ }
1499+ /* Many (perhaps most) of these colors will remain marked open. */
1500+ im->colorsTotal = gdMaxColors;
1501+ /*
1502+ ** Initialize the Compression routines
1503+ */
1504+ if (! ReadOK(fd,&c,1)) {
1505+ return;
1506+ }
1507+ if (LWZReadByte(fd, TRUE, c) < 0) {
1508+ return;
1509+ }
1510+
1511+ /*
1512+ ** If this is an "uninteresting picture" ignore it.
1513+ ** REMOVED For 1.4
1514+ */
1515+ /*if (ignore) { */
1516+ /* while (LWZReadByte(fd, FALSE, c) >= 0) */
1517+ /* ; */
1518+ /* return; */
1519+ /*} */
1520+
1521+ while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
1522+ /* This how we recognize which colors are actually used. */
1523+ if (im->open[v]) {
1524+ im->open[v] = 0;
1525+ }
1526+ gdImageSetPixel(im, xpos, ypos, v);
1527+ ++xpos;
1528+ if (xpos == len) {
1529+ xpos = 0;
1530+ if (interlace) {
1531+ switch (pass) {
1532+ case 0:
1533+ case 1:
1534+ ypos += 8; break;
1535+ case 2:
1536+ ypos += 4; break;
1537+ case 3:
1538+ ypos += 2; break;
1539+ }
1540+
1541+ if (ypos >= height) {
1542+ ++pass;
1543+ switch (pass) {
1544+ case 1:
1545+ ypos = 4; break;
1546+ case 2:
1547+ ypos = 2; break;
1548+ case 3:
1549+ ypos = 1; break;
1550+ default:
1551+ goto fini;
1552+ }
1553+ }
1554+ } else {
1555+ ++ypos;
1556+ }
1557+ }
1558+ if (ypos >= height)
1559+ break;
1560+ }
1561+
1562+fini:
1563+ if (LWZReadByte(fd,FALSE,c)>=0) {
1564+ /* Ignore extra */
1565+ }
1566+}
1567+
68381d70
JB
1568diff -Nur gd-2.0.17.orig/gd_gif_out.c gd-2.0.17/gd_gif_out.c
1569--- gd-2.0.17.orig/gd_gif_out.c 1970-01-01 01:00:00.000000000 +0100
1570+++ gd-2.0.17/gd_gif_out.c 2003-12-26 15:35:52.294570064 +0100
bd13356b
JB
1571@@ -0,0 +1,46 @@
1572+#include <stdio.h>
1573+#include <math.h>
1574+#include <string.h>
1575+#include <stdlib.h>
1576+#include "gd.h"
1577+
1578+/*
1579+** Wrapper functions for GIF output.
1580+*/
1581+
1582+#define LZW_LICENCED
1583+
1584+void gdImageGifToSink(gdImagePtr im, gdSinkPtr outSink)
1585+{
1586+ gdIOCtx *out = gdNewSSCtx(NULL,outSink);
1587+ gdImageGifCtx(im, out);
1588+ out->gd_free(out);
1589+}
1590+
1591+void gdImageGifCtx(gdImagePtr im, gdIOCtx *out)
1592+{
1593+#ifdef LZW_LICENCED
1594+ gdImageLzwCtx(im, out);
1595+#else
1596+ gdImageBigGifCtx(im, out);
1597+#endif
1598+}
1599+
1600+void gdImageGif(gdImagePtr im, FILE *outFile)
1601+{
1602+#ifdef LZW_LICENCED
1603+ gdImageLzw(im, outFile);
1604+#else
1605+ gdImageBigGif(im, outFile);
1606+#endif
1607+}
1608+
1609+void* gdImageGifPtr(gdImagePtr im, int *size)
1610+{
1611+#ifdef LZW_LICENCED
1612+ return gdImageLzwPtr(im, size);
1613+#else
1614+ return gdImageBigGifPtr(im, size);
1615+#endif
1616+}
1617+
68381d70
JB
1618diff -Nur gd-2.0.17.orig/gd.h gd-2.0.17/gd.h
1619--- gd-2.0.17.orig/gd.h 2003-12-24 20:55:14.000000000 +0100
1620+++ gd-2.0.17/gd.h 2003-12-26 15:35:52.276572800 +0100
1621@@ -240,6 +240,10 @@
1622
1623 gdImagePtr gdImageCreateFromPngSource (gdSourcePtr in);
1624
1625+ gdImagePtr gdImageCreateFromGif (FILE *fd);
1626+ gdImagePtr gdImageCreateFromGifCtx (gdIOCtxPtr in);
1627+ gdImagePtr gdImageCreateFromGifSource (gdSourcePtr in);
1628+
1629 gdImagePtr gdImageCreateFromGd (FILE * in);
1630 gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in);
1631
1632@@ -354,6 +358,7 @@
1633 gdPoint, *gdPointPtr;
1634
1635 void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1636+ void gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1637 void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1638
1639 /* These functions still work with truecolor images,
1640@@ -455,6 +460,14 @@
1641 /* Best to free this memory with gdFree(), not free() */
1642 void *gdImageJpegPtr (gdImagePtr im, int *size, int quality);
1643
1644+void gdImageLzw(gdImagePtr im, FILE *out);
1645+void* gdImageLzwPtr(gdImagePtr im, int *size);
1646+void gdImageLzwCtx(gdImagePtr im, gdIOCtxPtr out);
1647+
1648+void gdImageBigGif(gdImagePtr im, FILE *out);
1649+void* gdImageBigGifPtr(gdImagePtr im, int *size);
1650+void gdImageBigGifCtx(gdImagePtr im, gdIOCtxPtr out);
1651+
1652 /* A custom data sink. For backwards compatibility. Use
1653 gdIOCtx instead. */
1654 /* The sink function must return -1 on error, otherwise the number
1655@@ -469,6 +482,11 @@
1656
1657 void gdImagePngToSink (gdImagePtr im, gdSinkPtr out);
1658
1659+ void gdImageGif (gdImagePtr im, FILE *out);
1660+ void* gdImageGifPtr (gdImagePtr im, int *size);
1661+ void gdImageGifCtx (gdImagePtr im, gdIOCtxPtr out);
1662+ void gdImageGifToSink (gdImagePtr im, gdSinkPtr out);
1663+
1664 void gdImageGd (gdImagePtr im, FILE * out);
1665 void gdImageGd2 (gdImagePtr im, FILE * out, int cs, int fmt);
1666
1667diff -Nur gd-2.0.17.orig/gd_lzw_out.c gd-2.0.17/gd_lzw_out.c
1668--- gd-2.0.17.orig/gd_lzw_out.c 1970-01-01 01:00:00.000000000 +0100
1669+++ gd-2.0.17/gd_lzw_out.c 2003-12-26 15:35:52.300569152 +0100
bd13356b
JB
1670@@ -0,0 +1,796 @@
1671+#include <malloc.h>
1672+#include <stdio.h>
1673+#include <math.h>
1674+#include <string.h>
1675+#include <stdlib.h>
1676+#include "gd.h"
1677+
1678+/* Code drawn from ppmtogif.c, from the pbmplus package
1679+**
1680+** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
1681+** Lempel-Zim compression based on "compress".
1682+**
1683+** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
1684+**
1685+** Copyright (C) 1989 by Jef Poskanzer.
1686+**
1687+** Permission to use, copy, modify, and distribute this software and its
1688+** documentation for any purpose and without fee is hereby granted, provided
1689+** that the above copyright notice appear in all copies and that both that
1690+** copyright notice and this permission notice appear in supporting
1691+** documentation. This software is provided "as is" without express or
1692+** implied warranty.
1693+**
1694+** The Graphics Interchange Format(c) is the Copyright property of
1695+** CompuServe Incorporated. GIF(sm) is a Service Mark property of
1696+** CompuServe Incorporated.
1697+*/
1698+
1699+/*
1700+ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
1701+ */
1702+typedef int code_int;
1703+
1704+#ifdef SIGNED_COMPARE_SLOW
1705+typedef unsigned long int count_int;
1706+typedef unsigned short int count_short;
1707+#else /*SIGNED_COMPARE_SLOW*/
1708+typedef long int count_int;
1709+#endif /*SIGNED_COMPARE_SLOW*/
1710+
1711+static int colorstobpp(int colors);
1712+static void BumpPixel (void);
1713+static int GIFNextPixel (gdImagePtr im);
1714+static void GIFEncode (gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
1715+/*static void Putword (int w, gdIOCtx *fp); */
1716+static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im);
1717+static void output (code_int code);
1718+static void cl_block (void);
1719+static void cl_hash (register count_int hsize);
1720+static void char_init (void);
1721+static void char_out (int c);
1722+static void flush_char (void);
1723+/* Allows for reuse */
1724+static void init_statics(void);
1725+
1726+void gdImageLzwCtx(gdImagePtr im, gdIOCtx *out)
1727+{
1728+ int interlace, transparent, BitsPerPixel;
1729+
1730+ interlace = im->interlace;
1731+ transparent = im->transparent;
1732+
1733+ BitsPerPixel = colorstobpp(im->colorsTotal);
1734+ /* Clear any old values in statics strewn through the GIF code */
1735+ init_statics();
1736+ /* All set, let's do it. */
1737+ GIFEncode(
1738+ out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
1739+ im->red, im->green, im->blue, im);
1740+}
1741+
1742+void gdImageLzw(gdImagePtr im, FILE *outFile)
1743+{
1744+ gdIOCtx *out = gdNewFileCtx(outFile);
1745+ gdImageLzwCtx(im, out);
1746+ out->gd_free(out);
1747+}
1748+
1749+void* gdImageLzwPtr(gdImagePtr im, int *size)
1750+{
1751+ void *rv;
1752+ gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
1753+ gdImageLzwCtx(im, out);
1754+ rv = gdDPExtractData(out,size);
1755+ out->gd_free(out);
1756+ return rv;
1757+}
1758+
1759+
1760+
1761+static int
1762+colorstobpp(int colors)
1763+{
1764+ int bpp = 0;
1765+
1766+ if ( colors <= 2 )
1767+ bpp = 1;
1768+ else if ( colors <= 4 )
1769+ bpp = 2;
1770+ else if ( colors <= 8 )
1771+ bpp = 3;
1772+ else if ( colors <= 16 )
1773+ bpp = 4;
1774+ else if ( colors <= 32 )
1775+ bpp = 5;
1776+ else if ( colors <= 64 )
1777+ bpp = 6;
1778+ else if ( colors <= 128 )
1779+ bpp = 7;
1780+ else if ( colors <= 256 )
1781+ bpp = 8;
1782+ return bpp;
1783+ }
1784+
1785+/*****************************************************************************
1786+ *
1787+ * GIFENCODE.C - GIF Image compression interface
1788+ *
1789+ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
1790+ * BitsPerPixel, Red, Green, Blue, gdImagePtr )
1791+ *
1792+ *****************************************************************************/
1793+
1794+#define TRUE 1
1795+#define FALSE 0
1796+
1797+static int Width, Height;
1798+static int curx, cury;
1799+static long CountDown;
1800+static int Pass = 0;
1801+static int Interlace;
1802+
1803+/*
1804+ * Bump the 'curx' and 'cury' to point to the next pixel
1805+ */
1806+static void
1807+BumpPixel(void)
1808+{
1809+ /*
1810+ * Bump the current X position
1811+ */
1812+ ++curx;
1813+
1814+ /*
1815+ * If we are at the end of a scan line, set curx back to the beginning
1816+ * If we are interlaced, bump the cury to the appropriate spot,
1817+ * otherwise, just increment it.
1818+ */
1819+ if( curx == Width ) {
1820+ curx = 0;
1821+
1822+ if( !Interlace )
1823+ ++cury;
1824+ else {
1825+ switch( Pass ) {
1826+
1827+ case 0:
1828+ cury += 8;
1829+ if( cury >= Height ) {
1830+ ++Pass;
1831+ cury = 4;
1832+ }
1833+ break;
1834+
1835+ case 1:
1836+ cury += 8;
1837+ if( cury >= Height ) {
1838+ ++Pass;
1839+ cury = 2;
1840+ }
1841+ break;
1842+
1843+ case 2:
1844+ cury += 4;
1845+ if( cury >= Height ) {
1846+ ++Pass;
1847+ cury = 1;
1848+ }
1849+ break;
1850+
1851+ case 3:
1852+ cury += 2;
1853+ break;
1854+ }
1855+ }
1856+ }
1857+}
1858+
1859+/*
1860+ * Return the next pixel from the image
1861+ */
1862+static int
1863+GIFNextPixel(gdImagePtr im)
1864+{
1865+ int r;
1866+
1867+ if( CountDown == 0 )
1868+ return EOF;
1869+
1870+ --CountDown;
1871+
1872+ r = gdImageGetPixel(im, curx, cury);
1873+
1874+ BumpPixel();
1875+
1876+ return r;
1877+}
1878+
1879+/* public */
1880+
1881+static void
1882+GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
1883+{
1884+ int B;
1885+ int RWidth, RHeight;
1886+ int LeftOfs, TopOfs;
1887+ int Resolution;
1888+ int ColorMapSize;
1889+ int InitCodeSize;
1890+ int i;
1891+
1892+ Interlace = GInterlace;
1893+
1894+ ColorMapSize = 1 << BitsPerPixel;
1895+
1896+ RWidth = Width = GWidth;
1897+ RHeight = Height = GHeight;
1898+ LeftOfs = TopOfs = 0;
1899+
1900+ Resolution = BitsPerPixel;
1901+
1902+ /*
1903+ * Calculate number of bits we are expecting
1904+ */
1905+ CountDown = (long)Width * (long)Height;
1906+
1907+ /*
1908+ * Indicate which pass we are on (if interlace)
1909+ */
1910+ Pass = 0;
1911+
1912+ /*
1913+ * The initial code size
1914+ */
1915+ if( BitsPerPixel <= 1 )
1916+ InitCodeSize = 2;
1917+ else
1918+ InitCodeSize = BitsPerPixel;
1919+
1920+ /*
1921+ * Set up the current x and y position
1922+ */
1923+ curx = cury = 0;
1924+
1925+ /*
1926+ * Write the Magic header
1927+ */
1928+ gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
1929+
1930+ /*
1931+ * Write out the screen width and height
1932+ */
1933+ Putword( RWidth, fp );
1934+ Putword( RHeight, fp );
1935+
1936+ /*
1937+ * Indicate that there is a global colour map
1938+ */
1939+ B = 0x80; /* Yes, there is a color map */
1940+
1941+ /*
1942+ * OR in the resolution
1943+ */
1944+ B |= (Resolution - 1) << 5;
1945+
1946+ /*
1947+ * OR in the Bits per Pixel
1948+ */
1949+ B |= (BitsPerPixel - 1);
1950+
1951+ /*
1952+ * Write it out
1953+ */
1954+ gdPutC( B, fp );
1955+
1956+ /*
1957+ * Write out the Background colour
1958+ */
1959+ gdPutC( Background, fp );
1960+
1961+ /*
1962+ * Byte of 0's (future expansion)
1963+ */
1964+ gdPutC( 0, fp );
1965+
1966+ /*
1967+ * Write out the Global Colour Map
1968+ */
1969+ for( i=0; i<ColorMapSize; ++i ) {
1970+ gdPutC( Red[i], fp );
1971+ gdPutC( Green[i], fp );
1972+ gdPutC( Blue[i], fp );
1973+ }
1974+
1975+ /*
1976+ * Write out extension for transparent colour index, if necessary.
1977+ */
1978+ if ( Transparent >= 0 ) {
1979+ gdPutC( '!', fp );
1980+ gdPutC( 0xf9, fp );
1981+ gdPutC( 4, fp );
1982+ gdPutC( 1, fp );
1983+ gdPutC( 0, fp );
1984+ gdPutC( 0, fp );
1985+ gdPutC( (unsigned char) Transparent, fp );
1986+ gdPutC( 0, fp );
1987+ }
1988+
1989+ /*
1990+ * Write an Image separator
1991+ */
1992+ gdPutC( ',', fp );
1993+
1994+ /*
1995+ * Write the Image header
1996+ */
1997+
1998+ Putword( LeftOfs, fp );
1999+ Putword( TopOfs, fp );
2000+ Putword( Width, fp );
2001+ Putword( Height, fp );
2002+
2003+ /*
2004+ * Write out whether or not the image is interlaced
2005+ */
2006+ if( Interlace )
2007+ gdPutC( 0x40, fp );
2008+ else
2009+ gdPutC( 0x00, fp );
2010+
2011+ /*
2012+ * Write out the initial code size
2013+ */
2014+ gdPutC( InitCodeSize, fp );
2015+
2016+ /*
2017+ * Go and actually compress the data
2018+ */
2019+ compress( InitCodeSize+1, fp, im );
2020+
2021+ /*
2022+ * Write out a Zero-length packet (to end the series)
2023+ */
2024+ gdPutC( 0, fp );
2025+
2026+ /*
2027+ * Write the GIF file terminator
2028+ */
2029+ gdPutC( ';', fp );
2030+}
2031+
2032+/* */
2033+/* * Write out a word to the GIF file */
2034+/* */
2035+/*static void */
2036+/*Putword(int w, FILE *fp) */
2037+/*{ */
2038+/* fputc( w & 0xff, fp ); */
2039+/* fputc( (w / 256) & 0xff, fp ); */
2040+/*} */
2041+
2042+
2043+/***************************************************************************
2044+ *
2045+ * GIFCOMPR.C - GIF Image compression routines
2046+ *
2047+ * Lempel-Ziv compression based on 'compress'. GIF modifications by
2048+ * David Rowley (mgardi@watdcsu.waterloo.edu)
2049+ *
2050+ ***************************************************************************/
2051+
2052+/*
2053+ * General DEFINEs
2054+ */
2055+
2056+#define GIFBITS 12
2057+
2058+#define HSIZE 5003 /* 80% occupancy */
2059+
2060+#ifdef NO_UCHAR
2061+ typedef char char_type;
2062+#else /*NO_UCHAR*/
2063+ typedef unsigned char char_type;
2064+#endif /*NO_UCHAR*/
2065+
2066+/*
2067+ *
2068+ * GIF Image compression - modified 'compress'
2069+ *
2070+ * Based on: compress.c - File compression ala IEEE Computer, June 1984.
2071+ *
2072+ * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
2073+ * Jim McKie (decvax!mcvax!jim)
2074+ * Steve Davies (decvax!vax135!petsd!peora!srd)
2075+ * Ken Turkowski (decvax!decwrl!turtlevax!ken)
2076+ * James A. Woods (decvax!ihnp4!ames!jaw)
2077+ * Joe Orost (decvax!vax135!petsd!joe)
2078+ *
2079+ */
2080+#include <ctype.h>
2081+
2082+#define ARGVAL() (*++(*argv) || (--argc && *++argv))
2083+
2084+static int n_bits; /* number of bits/code */
2085+static int maxbits = GIFBITS; /* user settable max # bits/code */
2086+static code_int maxcode; /* maximum code, given n_bits */
2087+static code_int maxmaxcode = (code_int)1 << GIFBITS; /* should NEVER generate this code */
2088+#ifdef COMPATIBLE /* But wrong! */
2089+# define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)
2090+#else /*COMPATIBLE*/
2091+# define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
2092+#endif /*COMPATIBLE*/
2093+
2094+static count_int htab [HSIZE];
2095+static unsigned short codetab [HSIZE];
2096+#define HashTabOf(i) htab[i]
2097+#define CodeTabOf(i) codetab[i]
2098+
2099+static code_int hsize = HSIZE; /* for dynamic table sizing */
2100+
2101+/*
2102+ * To save much memory, we overlay the table used by compress() with those
2103+ * used by decompress(). The tab_prefix table is the same size and type
2104+ * as the codetab. The tab_suffix table needs 2**GIFBITS characters. We
2105+ * get this from the beginning of htab. The output stack uses the rest
2106+ * of htab, and contains characters. There is plenty of room for any
2107+ * possible stack (stack used to be 8000 characters).
2108+ */
2109+
2110+#define tab_prefixof(i) CodeTabOf(i)
2111+#define tab_suffixof(i) ((char_type*)(htab))[i]
2112+#define de_stack ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
2113+
2114+static code_int free_ent = 0; /* first unused entry */
2115+
2116+/*
2117+ * block compression parameters -- after all codes are used up,
2118+ * and compression rate changes, start over.
2119+ */
2120+static int clear_flg = 0;
2121+
2122+static int offset;
2123+static long int in_count = 1; /* length of input */
2124+static long int out_count = 0; /* # of codes output (for debugging) */
2125+
2126+/*
2127+ * compress stdin to stdout
2128+ *
2129+ * Algorithm: use open addressing double hashing (no chaining) on the
2130+ * prefix code / next character combination. We do a variant of Knuth's
2131+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
2132+ * secondary probe. Here, the modular division first probe is gives way
2133+ * to a faster exclusive-or manipulation. Also do block compression with
2134+ * an adaptive reset, whereby the code table is cleared when the compression
2135+ * ratio decreases, but after the table fills. The variable-length output
2136+ * codes are re-sized at this point, and a special CLEAR code is generated
2137+ * for the decompressor. Late addition: construct the table according to
2138+ * file size for noticeable speed improvement on small files. Please direct
2139+ * questions about this implementation to ames!jaw.
2140+ */
2141+
2142+static int g_init_bits;
2143+static gdIOCtx* g_outfile;
2144+
2145+static int ClearCode;
2146+static int EOFCode;
2147+
2148+static void
2149+compress(int init_bits, gdIOCtx *outfile, gdImagePtr im)
2150+{
2151+ register long fcode;
2152+ register code_int i /* = 0 */;
2153+ register int c;
2154+ register code_int ent;
2155+ register code_int disp;
2156+ register code_int hsize_reg;
2157+ register int hshift;
2158+
2159+ /*
2160+ * Set up the globals: g_init_bits - initial number of bits
2161+ * g_outfile - pointer to output file
2162+ */
2163+ g_init_bits = init_bits;
2164+ g_outfile = outfile;
2165+
2166+ /*
2167+ * Set up the necessary values
2168+ */
2169+ offset = 0;
2170+ out_count = 0;
2171+ clear_flg = 0;
2172+ in_count = 1;
2173+ maxcode = MAXCODE(n_bits = g_init_bits);
2174+
2175+ ClearCode = (1 << (init_bits - 1));
2176+ EOFCode = ClearCode + 1;
2177+ free_ent = ClearCode + 2;
2178+
2179+ char_init();
2180+
2181+ ent = GIFNextPixel( im );
2182+
2183+ hshift = 0;
2184+ for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
2185+ ++hshift;
2186+ hshift = 8 - hshift; /* set hash code range bound */
2187+
2188+ hsize_reg = hsize;
2189+ cl_hash( (count_int) hsize_reg); /* clear hash table */
2190+
2191+ output( (code_int)ClearCode );
2192+
2193+#ifdef SIGNED_COMPARE_SLOW
2194+ while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {
2195+#else /*SIGNED_COMPARE_SLOW*/
2196+ while ( (c = GIFNextPixel( im )) != EOF ) { /* } */
2197+#endif /*SIGNED_COMPARE_SLOW*/
2198+
2199+ ++in_count;
2200+
2201+ fcode = (long) (((long) c << maxbits) + ent);
2202+ i = (((code_int)c << hshift) ^ ent); /* xor hashing */
2203+
2204+ if ( HashTabOf (i) == fcode ) {
2205+ ent = CodeTabOf (i);
2206+ continue;
2207+ } else if ( (long)HashTabOf (i) < 0 ) /* empty slot */
2208+ goto nomatch;
2209+ disp = hsize_reg - i; /* secondary hash (after G. Knott) */
2210+ if ( i == 0 )
2211+ disp = 1;
2212+probe:
2213+ if ( (i -= disp) < 0 )
2214+ i += hsize_reg;
2215+
2216+ if ( HashTabOf (i) == fcode ) {
2217+ ent = CodeTabOf (i);
2218+ continue;
2219+ }
2220+ if ( (long)HashTabOf (i) > 0 )
2221+ goto probe;
2222+nomatch:
2223+ output ( (code_int) ent );
2224+ ++out_count;
2225+ ent = c;
2226+#ifdef SIGNED_COMPARE_SLOW
2227+ if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
2228+#else /*SIGNED_COMPARE_SLOW*/
2229+ if ( free_ent < maxmaxcode ) { /* } */
2230+#endif /*SIGNED_COMPARE_SLOW*/
2231+ CodeTabOf (i) = free_ent++; /* code -> hashtable */
2232+ HashTabOf (i) = fcode;
2233+ } else
2234+ cl_block();
2235+ }
2236+ /*
2237+ * Put out the final code.
2238+ */
2239+ output( (code_int)ent );
2240+ ++out_count;
2241+ output( (code_int) EOFCode );
2242+}
2243+
2244+/*****************************************************************
2245+ * TAG( output )
2246+ *
2247+ * Output the given code.
2248+ * Inputs:
2249+ * code: A n_bits-bit integer. If == -1, then EOF. This assumes
2250+ * that n_bits =< (long)wordsize - 1.
2251+ * Outputs:
2252+ * Outputs code to the file.
2253+ * Assumptions:
2254+ * Chars are 8 bits long.
2255+ * Algorithm:
2256+ * Maintain a GIFBITS character long buffer (so that 8 codes will
2257+ * fit in it exactly). Use the VAX insv instruction to insert each
2258+ * code in turn. When the buffer fills up empty it and start over.
2259+ */
2260+
2261+static unsigned long cur_accum = 0;
2262+static int cur_bits = 0;
2263+
2264+static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
2265+ 0x001F, 0x003F, 0x007F, 0x00FF,
2266+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
2267+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
2268+
2269+static void
2270+output(code_int code)
2271+{
2272+ cur_accum &= masks[ cur_bits ];
2273+
2274+ if( cur_bits > 0 )
2275+ cur_accum |= ((long)code << cur_bits);
2276+ else
2277+ cur_accum = code;
2278+
2279+ cur_bits += n_bits;
2280+
2281+ while( cur_bits >= 8 ) {
2282+ char_out( (unsigned int)(cur_accum & 0xff) );
2283+ cur_accum >>= 8;
2284+ cur_bits -= 8;
2285+ }
2286+
2287+ /*
2288+ * If the next entry is going to be too big for the code size,
2289+ * then increase it, if possible.
2290+ */
2291+ if ( free_ent > maxcode || clear_flg ) {
2292+
2293+ if( clear_flg ) {
2294+
2295+ maxcode = MAXCODE (n_bits = g_init_bits);
2296+ clear_flg = 0;
2297+
2298+ } else {
2299+
2300+ ++n_bits;
2301+ if ( n_bits == maxbits )
2302+ maxcode = maxmaxcode;
2303+ else
2304+ maxcode = MAXCODE(n_bits);
2305+ }
2306+ }
2307+
2308+ if( code == EOFCode ) {
2309+ /*
2310+ * At EOF, write the rest of the buffer.
2311+ */
2312+ while( cur_bits > 0 ) {
2313+ char_out( (unsigned int)(cur_accum & 0xff) );
2314+ cur_accum >>= 8;
2315+ cur_bits -= 8;
2316+ }
2317+
2318+ flush_char();
2319+
2320+/* fflush( g_outfile ); */
2321+/* */
2322+/* if( ferror( g_outfile ) ) */
2323+/* return; */
2324+ }
2325+}
2326+
2327+/*
2328+ * Clear out the hash table
2329+ */
2330+static void
2331+cl_block (void) /* table clear for block compress */
2332+{
2333+
2334+ cl_hash ( (count_int) hsize );
2335+ free_ent = ClearCode + 2;
2336+ clear_flg = 1;
2337+
2338+ output( (code_int)ClearCode );
2339+}
2340+
2341+static void
2342+cl_hash(register count_int hsize) /* reset code table */
2343+
2344+{
2345+
2346+ register count_int *htab_p = htab+hsize;
2347+
2348+ register long i;
2349+ register long m1 = -1;
2350+
2351+ i = hsize - 16;
2352+ do { /* might use Sys V memset(3) here */
2353+ *(htab_p-16) = m1;
2354+ *(htab_p-15) = m1;
2355+ *(htab_p-14) = m1;
2356+ *(htab_p-13) = m1;
2357+ *(htab_p-12) = m1;
2358+ *(htab_p-11) = m1;
2359+ *(htab_p-10) = m1;
2360+ *(htab_p-9) = m1;
2361+ *(htab_p-8) = m1;
2362+ *(htab_p-7) = m1;
2363+ *(htab_p-6) = m1;
2364+ *(htab_p-5) = m1;
2365+ *(htab_p-4) = m1;
2366+ *(htab_p-3) = m1;
2367+ *(htab_p-2) = m1;
2368+ *(htab_p-1) = m1;
2369+ htab_p -= 16;
2370+ } while ((i -= 16) >= 0);
2371+
2372+ for ( i += 16; i > 0; --i )
2373+ *--htab_p = m1;
2374+}
2375+
2376+/******************************************************************************
2377+ *
2378+ * GIF Specific routines
2379+ *
2380+ ******************************************************************************/
2381+
2382+/*
2383+ * Number of characters so far in this 'packet'
2384+ */
2385+static int a_count;
2386+
2387+/*
2388+ * Set up the 'byte output' routine
2389+ */
2390+static void
2391+char_init(void)
2392+{
2393+ a_count = 0;
2394+}
2395+
2396+/*
2397+ * Define the storage for the packet accumulator
2398+ */
2399+static char accum[ 256 ];
2400+
2401+/*
2402+ * Add a character to the end of the current packet, and if it is 254
2403+ * characters, flush the packet to disk.
2404+ */
2405+static void
2406+char_out(int c)
2407+{
2408+ accum[ a_count++ ] = c;
2409+ if( a_count >= 254 )
2410+ flush_char();
2411+}
2412+
2413+/*
2414+ * Flush the packet to disk, and reset the accumulator
2415+ */
2416+static void
2417+flush_char(void)
2418+{
2419+ if( a_count > 0 ) {
2420+ gdPutC( a_count, g_outfile );
2421+ gdPutBuf( accum, a_count, g_outfile );
2422+ a_count = 0;
2423+ }
2424+}
2425+
2426+static void init_statics(void) {
2427+ /* Some of these are properly initialized later. What I'm doing
2428+ here is making sure code that depends on C's initialization
2429+ of statics doesn't break when the code gets called more
2430+ than once. */
2431+ Width = 0;
2432+ Height = 0;
2433+ curx = 0;
2434+ cury = 0;
2435+ CountDown = 0;
2436+ Pass = 0;
2437+ Interlace = 0;
2438+ a_count = 0;
2439+ cur_accum = 0;
2440+ cur_bits = 0;
2441+ g_init_bits = 0;
2442+ g_outfile = 0;
2443+ ClearCode = 0;
2444+ EOFCode = 0;
2445+ free_ent = 0;
2446+ clear_flg = 0;
2447+ offset = 0;
2448+ in_count = 1;
2449+ out_count = 0;
2450+ hsize = HSIZE;
2451+ n_bits = 0;
2452+ maxbits = GIFBITS;
2453+ maxcode = 0;
2454+ maxmaxcode = (code_int)1 << GIFBITS;
2455+}
2456+
2457+
2458+/* +-------------------------------------------------------------------+ */
2459+/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
2460+/* | Permission to use, copy, modify, and distribute this software | */
2461+/* | and its documentation for any purpose and without fee is hereby | */
2462+/* | granted, provided that the above copyright notice appear in all | */
2463+/* | copies and that both that copyright notice and this permission | */
2464+/* | notice appear in supporting documentation. This software is | */
2465+/* | provided "as is" without express or implied warranty. | */
2466+/* +-------------------------------------------------------------------+ */
68381d70
JB
2467diff -Nur gd-2.0.17.orig/gdtest.c gd-2.0.17/gdtest.c
2468--- gd-2.0.17.orig/gdtest.c 2003-03-29 16:46:35.000000000 +0100
2469+++ gd-2.0.17/gdtest.c 2003-12-26 15:35:52.313567176 +0100
2470@@ -91,6 +91,59 @@
bd13356b
JB
2471 gdImageDestroy (im2);
2472 ctx->gd_free (ctx);
2473
2474+ /* */
2475+ /* Send to GIF File then Ptr */
2476+ /* */
2477+ sprintf(of, "%s.gif", argv[1]);
2478+ out = fopen(of, "wb");
2479+ gdImageGif(im, out);
2480+ fclose(out);
2481+
2482+ in = fopen(of, "rb");
2483+ if (!in) {
2484+ fprintf(stderr, "GIF Output file does not exist!\n");
2485+ exit(1);
2486+ }
2487+ im2 = gdImageCreateFromGif(in);
2488+ fclose(in);
2489+
2490+ CompareImages("GD->GIF File->GD", ref, im2);
2491+
2492+ gdImageDestroy(im2);
2493+
2494+ /*
2495+ ** Test gdImageCreateFromGifSource
2496+ **/
2497+
2498+ in = fopen(of, "rb");
2499+
2500+ if (!in)
2501+ {
2502+ fprintf (stderr, "GD Source: ERROR - GD Source input file does not exist - Sink may have failed!\n");
2503+ };
2504+
2505+ imgsrc.source = freadWrapper;
2506+ imgsrc.context = in;
2507+ im2 = gdImageCreateFromGifSource(&imgsrc);
2508+ fclose(in);
2509+
2510+ if (im2 == NULL) {
2511+ printf("GD Source (GIF): ERROR Null returned by gdImageCreateFromGifSource\n");
2512+ } else {
2513+ CompareImages("GD Source (GIF)", ref, im2);
2514+ gdImageDestroy(im2);
2515+ };
2516+
2517+ unlink(of);
2518+
2519+ iptr = gdImageGifPtr(im,&sz);
2520+ ctx = gdNewDynamicCtx(sz,iptr);
2521+ im2 = gdImageCreateFromGifCtx(ctx);
2522+
2523+ CompareImages("GD->GIF ptr->GD", ref, im2);
2524+
2525+ gdImageDestroy(im2);
2526+ ctx->gd_free(ctx);
2527
2528 /* */
2529 /* Send to GD2 File then Ptr */
68381d70 2530@@ -209,8 +262,6 @@
bd13356b
JB
2531 gdImageDestroy (im2);
2532 };
2533
2534- unlink (of);
2535-
2536 /* */
2537 /* Test Extraction */
2538 /* */
68381d70 2539@@ -277,6 +328,10 @@
bd13356b
JB
2540 printf ("[Merged Image has %d colours]\n", im2->colorsTotal);
2541 CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3);
2542
2543+ out = fopen ("test/gdtest_merge_out.png", "wb");
2544+ gdImagePng(im2, out);
2545+ close(out);
2546+
2547 gdImageDestroy (im2);
2548 gdImageDestroy (im3);
2549
68381d70
JB
2550diff -Nur gd-2.0.17.orig/gdtestft.c gd-2.0.17/gdtestft.c
2551--- gd-2.0.17.orig/gdtestft.c 2003-03-29 16:46:35.000000000 +0100
2552+++ gd-2.0.17/gdtestft.c 2003-12-26 15:35:52.316566720 +0100
bd13356b
JB
2553@@ -23,6 +23,8 @@
2554 #define MAXY(x) MAX4(x[1],x[3],x[5],x[7])
2555 #define MINY(x) MIN4(x[1],x[3],x[5],x[7])
2556
2557+void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2);
2558+
2559 int
2560 main (int argc, char *argv[])
2561 {
68381d70
JB
2562diff -Nur gd-2.0.17.orig/giftogd2.c gd-2.0.17/giftogd2.c
2563--- gd-2.0.17.orig/giftogd2.c 1970-01-01 01:00:00.000000000 +0100
2564+++ gd-2.0.17/giftogd2.c 2003-12-26 15:35:52.319566264 +0100
bd13356b
JB
2565@@ -0,0 +1,48 @@
2566+#include <stdio.h>
2567+#include <stdlib.h>
2568+
2569+#include "gd.h"
2570+
2571+/* A short program which converts a .gif file into a .gd file, for
2572+ your convenience in creating images on the fly from a
2573+ basis image that must be loaded quickly. The .gd format
2574+ is not intended to be a general-purpose format. */
2575+
2576+int main(int argc, char **argv)
2577+{
2578+ gdImagePtr im;
2579+ FILE *in, *out;
2580+ int cs, fmt;
2581+
2582+ if (argc != 5) {
2583+ fprintf(stderr, "Usage: giftogd2 filename.gif filename.gd2 cs fmt\n");
2584+ fprintf(stderr, " where cs is the chunk size\n");
2585+ fprintf(stderr, " fmt is 1 for raw, 2 for compressed\n");
2586+ exit(1);
2587+ }
2588+ in = fopen(argv[1], "rb");
2589+ if (!in) {
2590+ fprintf(stderr, "Input file does not exist!\n");
2591+ exit(1);
2592+ }
2593+ im = gdImageCreateFromGif(in);
2594+ fclose(in);
2595+ if (!im) {
2596+ fprintf(stderr, "Input is not in GIF format!\n");
2597+ exit(1);
2598+ }
2599+ out = fopen(argv[2], "wb");
2600+ if (!out) {
2601+ fprintf(stderr, "Output file cannot be written to!\n");
2602+ gdImageDestroy(im);
2603+ exit(1);
2604+ }
2605+ cs = atoi(argv[3]);
2606+ fmt = atoi(argv[4]);
2607+ gdImageGd2(im, out, cs, fmt);
2608+ fclose(out);
2609+ gdImageDestroy(im);
2610+
2611+ return 0;
2612+}
2613+
68381d70
JB
2614diff -Nur gd-2.0.17.orig/index.html gd-2.0.17/index.html
2615--- gd-2.0.17.orig/index.html 2003-12-25 17:43:52.000000000 +0100
2616+++ gd-2.0.17/index.html 2003-12-26 15:38:31.022439760 +0100
bd13356b
JB
2617@@ -28,7 +28,12 @@
2618 more compatible with the major Web browsers than even PNG is. WBMP is
2619 intended for wireless devices (not regular web browsers). Old
2620 code will need modification to call gdImagePng or gdImageJpeg instead
2621-of gdImageGif. <strong>Please do not ask us to send you the old GIF
2622+of gdImageGif.
2623+<p>
2624+Note: The version at this site also supports GIF format, for those people
2625+who have not yet managed to move away from GIFs.
2626+<p>
2627+<strong>Please do not ask the original author to send you the old GIF
68381d70
JB
2628 version of GD.</strong> Yes, Unisys still holds a patent on the LZW compression
2629 algorithm in some countries. The best
bd13356b 2630 solution is to move to legally unencumbered, well-compressed,
68381d70 2631@@ -117,6 +122,18 @@
bd13356b
JB
2632 Portions relating to WBMP copyright 2000, 2001, 2002 Maurice Szmurlo and Johan Van
2633 den Brande.
2634 <p>
2635+GIF decompression code copyright 1990, 1991, 1993, by David Koblas
2636+(koblas@netcom.com).
2637+<p>
2638+Non-LZW-based GIF compression code copyright 1998, by Hutchison Avenue
2639+Software Corporation (<a href="http://www.hasc.com">http://www.hasc.com/</a>,
2640+info@hasc.com).
2641+<p>
2642+LZW-based GIF compression code David Rowley.
2643+Obtaining a license for the Unisys LZW compression patent is
2644+entirely between the user and Unisys. The authors of gd can provide
2645+NO assistance in this matter.
2646+<p>
2647 <strong>Permission has been granted to copy, distribute and modify gd in any
2648 context without fee, including a commercial application, provided that this notice
2649 is present in user-accessible supporting documentation.</strong>
68381d70 2650@@ -202,6 +219,24 @@
bd13356b
JB
2651 <ul>
2652 <li><a href="http://martin.gleeson.com/fly/">fly</a>, by Martin Gleeson
2653 </ul>
2654+<P><A NAME="gifpatch"><H3>What's new in the patched version?</H3></A>
2655+
2656+This version reinstates GIF support. Specifically, the following functions are added:
2657+<ul>
2658+<li><a href=#gdImageOpenPolygon>gdImageOpenPolygon</a>. This is basically the same as
2659+gdImagePolygon, but it does not join the start and end points. It is required by GD.pm.
2660+<li><a href=#gdImageGif>gdImageGif</a>
2661+<li><a href=#gdImageGifPtr>gdImageGifPtr</a>
2662+<li><a href=#gdImageGifCtx>gdImageGifCtx</a>
2663+<li><a href=#gdImageGifToSink>gdImageGifToSink</a>
2664+<li><a href=#gdImageCreateFromGif>gdImageCreateFromGif</a>
2665+<li><a href=#gdImageCreateFromGifCtx>gdImageCreateFromGifCtx</a>
2666+<li>Other functions added, but not documented, are: gdImageLzw, gdImageLzwPtr,
2667+gdImageLzwCtx, gdImageBigGif, gdImageBigGifPtr, gdImageBigGifCtx.
2668+</ul>
2669+<p>
2670+Note: While every effort has been made to ensure that the _WinNT_ build works, it has not
2671+been tested.
2672 <P>
68381d70 2673 <A NAME="whatsnew2.0.17"><H3>What's new in version 2.0.17?</H3></A>
bd13356b 2674 <P>
68381d70 2675@@ -659,6 +694,7 @@
bd13356b
JB
2676 preprocessing them, this should not be a big problem. gd 2.0 should
2677 read old .gd and .gd2 files correctly.
2678 </ul>
2679+
2680 <P><A NAME="whatsnew1.8.4"><H3>What's new in version 1.8.4?</H3></A>
2681 <ul>
68381d70
JB
2682 <li>Add support for FreeType2 (John Ellson ellson@graphviz.org)
2683@@ -691,6 +727,7 @@
bd13356b
JB
2684 corrected
2685 <li>Updated links to fast-moving, always dodging libpng and zlib web sites
2686 </ul>
2687+
2688 <P><A NAME="whatsnew1.8.1"><H3>What's new in version 1.8.1?</H3></A>
2689 <ul>
2690 <li>Optional components no longer built by default (following the
68381d70 2691@@ -768,6 +805,7 @@
bd13356b
JB
2692 <a href="#gdImageCreateFromXpm"><code>gdImageCreateFromXpm</code></a>
2693 function, if the Xpm library is available. Thanks to Caolan McNamara.
2694 </ul>
2695+
2696 <P><A NAME="whatsnew1.6.3"><H3>What's new in version 1.6.3?</H3></A>
2697 Version 1.6.3 corrects a memory leak in gd_png.c. This leak caused
2698 a significant amount of memory to be allocated and not freed when
68381d70 2699@@ -1334,7 +1372,8 @@
bd13356b
JB
2700 <DT><A NAME="gdPoint">gdPoint</A> <strong>(TYPE)</strong>
2701 <DD>
2702 Represents a point in the coordinate space of the image; used
2703-by <A HREF="#gdImagePolygon">gdImagePolygon</A> and
2704+by <A HREF="#gdImagePolygon">gdImagePolygon</A>,
2705+<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A>, and
2706 <A HREF="#gdImageFilledPolygon">gdImageFilledPolygon</A>.
2707 <PRE>
2708 typedef struct {
68381d70 2709@@ -1344,7 +1383,8 @@
bd13356b
JB
2710 <DT><A NAME="gdPointPtr">gdPointPtr</A> <strong>(TYPE)</strong>
2711 <DD>
2712 A pointer to a <A HREF="#gdPoint">gdPoint</A> structure; passed
2713-as an argument to <A HREF="#gdImagePolygon">gdImagePolygon</A>
2714+as an argument to <A HREF="#gdImagePolygon">gdImagePolygon</A>,
2715+<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A>,
2716 and <A HREF="#gdImageFilledPolygon">gdImageFilledPolygon</A>.
2717 </DL>
2718 <DT><A NAME="gdFTStringExtra">gdFTStringExtra</a> <strong>(TYPE)</strong>
68381d70 2719@@ -1457,6 +1497,75 @@
bd13356b
JB
2720 /* ... Use the image ... */
2721 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2722 </PRE>
2723+
2724+<DT><A NAME="gdImageCreateFromGif">gdImageCreateFromGif(FILE *in)</A>
2725+<strong>(FUNCTION)</strong>
2726+<BR><A NAME="gdImageCreateFromGifCtx">gdImageCreateFromGifCtx(<a href=#gdioctx>gdIOCtx</a> *in)</A>
2727+<strong>(FUNCTION)</strong>
2728+<p>
2729+<DD>
2730+gdImageCreateFromGif is called to load images from GIF format files.
2731+Invoke gdImageCreateFromGif with an already opened pointer to a file
2732+containing the desired image.
2733+gdImageCreateFromGif
2734+returns a <A HREF="#gdImagePtr">gdImagePtr</A> to the new image, or NULL
2735+if unable to load the image (most often because the file is corrupt or
2736+does not contain a GIF image). gdImageCreateFromGif does <em>not</em>
2737+close the file. You can inspect the sx and sy members of the
2738+image to determine its size. The image must eventually be destroyed
2739+using <A HREF="#gdImageDestroy">gdImageDestroy()</A>.
2740+<PRE>
2741+<A HREF="#gdImagePtr">gdImagePtr</A> im;
2742+... inside a function ...
2743+FILE *in;
2744+in = fopen("mygif.gif", "rb");
2745+im = gdImageCreateFromGif(in);
2746+fclose(in);
2747+/* ... Use the image ... */
2748+<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2749+</PRE>
2750+<DT><A NAME="gdImageCreateFromGifSource">gdImageCreateFromGifSource(gdSourcePtr in)</A>
2751+<strong>(FUNCTION)</strong>
2752+<dd>
2753+gdImageCreateFromGifSource is called to load a GIF from
2754+a data source other than a file. Usage is very similar to
2755+the <a href="#gdImageCreateFromGif">gdImageCreateFromGif</a> function,
2756+except that the programmer provides a custom data source.
2757+<p>
2758+The programmer must write an input function which accepts
2759+a context pointer, a buffer, and a number of bytes to be
2760+read as arguments. This function must read the number of
2761+bytes requested, unless the end of the file has been reached,
2762+in which case the function should return zero, or an error
2763+has occurred, in which case the function should return
2764+<code>-1</code>. The programmer then creates a
2765+<a href="#gdSource">gdSource</a> structure and sets
2766+the <code>source</code> pointer to the input function and
2767+the context pointer to any value which is useful to the
2768+programmer.
2769+<p>
2770+The example below
2771+implements <a href="#gdImageCreateFromGif">gdImageCreateFromGif</a>
2772+by creating a custom data source and invoking gdImageCreateFromGifSource.
2773+<pre>
2774+static int freadWrapper(void *context, char *buf, int len);
2775+
2776+gdImagePtr gdImageCreateFromGif(FILE *in)
2777+{
2778+ gdSource s;
2779+ s.source = freadWrapper;
2780+ s.context = in;
2781+ return gdImageCreateFromGifSource(&s);
2782+}
2783+
2784+static int freadWrapper(void *context, char *buf, int len)
2785+{
2786+ int got = fread(buf, 1, len, (FILE *) context);
2787+ return got;
2788+}
2789+</pre>
2790+
2791+
2792 <DT><A NAME="gdImageCreateFromPng">gdImageCreateFromPng(FILE *in)</A>
2793 <strong>(FUNCTION)</strong>
2794 <BR><A NAME="gdImageCreateFromPngCtx">gdImageCreateFromPngCtx(<a href=#gdioctx>gdIOCtx</a> *in)</A>
68381d70 2795@@ -1672,6 +1781,92 @@
bd13356b
JB
2796 /* Now destroy it */
2797 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2798 </PRE>
2799+
2800+<DT><A NAME="gdImageGif">
2801+void gdImageGif(gdImagePtr im, FILE *out)</A>
2802+<STRONG>(FUNCTION)</STRONG>
2803+<DD>
2804+gdImageGif outputs the specified image to the specified
2805+file in GIF format. The file must be open for writing. Under MSDOS
2806+and all versions of Windows, it is important to use "wb" as opposed
2807+to simply "w" as the mode when opening the file, and under Unix there
2808+is no penalty for doing so. gdImageGif does <em>not</em>
2809+close the file; your code must do so.
2810+<PRE>
2811+... inside a function ...
2812+<A HREF="#gdImagePtr">gdImagePtr</A> im;
2813+int black, white;
2814+FILE *out;
2815+/* Create the image */
2816+im = <A HREF="#gdImageCreate">gdImageCreate</A>(100, 100);
2817+/* Allocate background */
2818+white = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 255, 255, 255);
2819+/* Allocate drawing color */
2820+black = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 0, 0, 0);
2821+/* Draw rectangle */
2822+<A HREF="#gdImageRectangle">gdImageRectangle</A>(im, 0, 0, 99, 99, black);
2823+/* Open output file in binary mode */
2824+out = fopen("rect.gif", "wb");
2825+/* Write GIF */
2826+gdImageGif(im, out);
2827+/* Close file */
2828+fclose(out);
2829+/* Destroy image */
2830+<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2831+</PRE>
2832+
2833+<DT><A NAME="gdImageGifCtx">
2834+void* gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)</A>
2835+<STRONG>(FUNCTION)</STRONG>
2836+<DD>Identical to gdImageGif except that it writes the GIF to a
2837+<a href=#gdIOCtx>gdIOCtx</a>.
2838+<p>
2839+<DT><A NAME="gdImageGifPtr">
2840+void* gdImageGifPtr(gdImagePtr im, int *size)</A>
2841+<STRONG>(FUNCTION)</STRONG>
2842+<DD>Identical to gdImageGif except that it returns a pointer to a memory
2843+area with the GIF data. This memory must be freed by the caller when it is
2844+no longer needed. The 'size' parameter received the total size of the block
2845+of memory.
2846+<p>
2847+
2848+<DT><A NAME="gdImageGifToSink">gdImageGifToSink(gdImagePtr im, gdSinkPtr out)</A>
2849+<strong>(FUNCTION)</strong>
2850+<dd>
2851+gdImageGifToSink is called to write a GIF to
2852+a data "sink" (destination) other than a file. Usage is very similar to
2853+the <a href="#gdImageGif">gdImageGif</a> function,
2854+except that the programmer provides a custom data sink.
2855+<p>
2856+The programmer must write an output function which accepts
2857+a context pointer, a buffer, and a number of bytes to be
2858+written as arguments. This function must write the number of
2859+bytes requested and return that number, unless an error
2860+has occurred, in which case the function should return
2861+<code>-1</code>. The programmer then creates a
2862+<a href="#gdSink">gdSink</a> structure and sets
2863+the <code>sink</code> pointer to the output function and
2864+the context pointer to any value which is useful to the
2865+programmer.
2866+<p>
2867+The example below
2868+implements <a href="#gdImageGif">gdImageGif</a>
2869+by creating a custom data source and invoking gdImageGifFromSink.
2870+<pre>
2871+static int stdioSink(void *context, char *buffer, int len)
2872+{
2873+ return fwrite(buffer, 1, len, (FILE *) context);
2874+}
2875+
2876+void gdImageGif(gdImagePtr im, FILE *out)
2877+{
2878+ gdSink mySink;
2879+ mySink.context = (void *) out;
2880+ mySink.sink = stdioSink;
2881+ gdImageGifToSink(im, &mySink);
2882+}
2883+</pre>
2884+
2885 <DT><A NAME="gdImageJpeg">
2886 void gdImageJpeg(gdImagePtr im, FILE *out, int quality)</A>
2887 <STRONG>(FUNCTION)</STRONG><BR>
68381d70 2888@@ -2133,6 +2328,15 @@
bd13356b
JB
2889 /* Destroy it */
2890 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2891 </PRE>
2892+
2893+<DT><A NAME="gdImageOpenPolygon">void gdImageOpenPolygon(gdImagePtr im, gdPointPtr points, int pointsTotal, int color)</A>
2894+<STRONG>(FUNCTION)</STRONG>
2895+<DD>
2896+gdImageOpenPolygon is used to draw an open polygon (ie. series of line segments). It is almost identical
2897+to <A HREF="#gdImagePolygon">gdImagePolygon</A>, except that it does not join the last point to the
2898+first point.
2899+<P>
2900+
2901 <DT><A NAME="gdImageRectangle">void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)</A>
2902 <STRONG>(FUNCTION)</STRONG>
2903 <DD>
68381d70
JB
2904@@ -4488,6 +4692,9 @@
2905 <A HREF="#gdImageCreateFromGd2Ctx">gdImageCreateFromGd2Ctx</A> |
bd13356b 2906 <A HREF="#gdImageCreateFromGd2Part">gdImageCreateFromGd2Part</A> |
68381d70 2907 <A HREF="#gdImageCreateFromGd2PartCtx">gdImageCreateFromGd2PartCtx</A> |
bd13356b
JB
2908+<A HREF="#gdImageCreateFromGif">gdImageCreateFromGif</A> |
2909+<A HREF="#gdImageCreateFromGifCtx">gdImageCreateFromGifCtx</A> |
2910+<A HREF="#gdImageCreateFromGifSource">gdImageCreateFromGifSource</A> |
2911 <A HREF="#gdImageCreateFromJpeg">gdImageCreateFromJpeg</A> |
68381d70 2912 <A HREF="#gdImageCreateFromJpegCtx">gdImageCreateFromJpegCtx</A> |
bd13356b 2913 <A HREF="#gdImageCreateFromPng">gdImageCreateFromPng</A> |
68381d70 2914@@ -4507,6 +4714,10 @@
bd13356b
JB
2915 <A HREF="#gdImageGetInterlaced">gdImageGetInterlaced</A> |
2916 <A HREF="#gdImageGetPixel">gdImageGetPixel</A> |
2917 <A HREF="#gdImageGetTransparent">gdImageGetTransparent</A> |
2918+<A HREF="#gdImageGif">gdImageGif</A> |
2919+<A HREF="#gdImageGifCtx">gdImageGifCtx</A> |
2920+<A HREF="#gdImageGifPtr">gdImageGifPtr</A> |
2921+<A HREF="#gdImageGifToSink">gdImageGifToSink</A> |
2922 <A HREF="#gdImageGreen">gdImageGreen</A> |
2923 <A HREF="#gdImageInterlace">gdImageInterlace</A> |
2924 <A HREF="#gdImageJpeg">gdImageJpeg</A> |
68381d70
JB
2925@@ -4522,6 +4733,7 @@
2926 <A HREF="#gdImagePngPtrEx">gdImagePngPtrEx</A> |
bd13356b
JB
2927 <A HREF="#gdImagePngToSink">gdImagePngToSink</A> |
2928 <A HREF="#gdImagePolygon">gdImagePolygon</A> |
2929+<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A> |
2930 <A HREF="#gdImagePtr">gdImagePtr</A> |
2931 <A HREF="#gdImageWBMP">gdImageWBMP</A> |
68381d70
JB
2932 <A HREF="#gdImageWBMPCtx">gdImageWBMPCtx</A> |
2933diff -Nur gd-2.0.17.orig/Makefile.am gd-2.0.17/Makefile.am
2934--- gd-2.0.17.orig/Makefile.am 2003-12-25 02:50:00.000000000 +0100
2935+++ gd-2.0.17/Makefile.am 2003-12-26 15:36:42.047006544 +0100
2936@@ -5,7 +5,7 @@
2937
2938 SUBDIRS = config test
2939
2940-bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng
2941+bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng gd2togif gdcmpgif giftogd2
2942
2943 bin_SCRIPTS = bdftogd
2944
2945@@ -17,7 +17,7 @@
2946
2947 lib_LTLIBRARIES = libgd.la
2948
2949-libgd_la_SOURCES = gd.c gdfx.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h
2950+libgd_la_SOURCES = gd.c gdfx.c gd_gd.c gd_gd2.c gd_io.c gd_io_dp.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_topal.c gd_wbmp.c gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c gdft.c gdhelpers.c gdhelpers.h gdkanji.c gdtables.c gdxpm.c jisx0208.h wbmp.c wbmp.h gd_gif_in.c gd_gif_out.c gd_biggif_out.c gd_lzw_out.c
2951
2952 libgd_la_LDFLAGS = -version-info 2:0:0
2953
2954