1 diff -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
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. */
13 +int main(int argc, char **argv)
18 + fprintf(stderr, "Usage: gd2togif filename.gd2 filename.gif\n");
21 + in = fopen(argv[1], "rb");
23 + fprintf(stderr, "Input file does not exist!\n");
26 + im = gdImageCreateFromGd2(in);
29 + fprintf(stderr, "Input is not in GIF format!\n");
32 + out = fopen(argv[2], "wb");
34 + fprintf(stderr, "Output file cannot be written to!\n");
38 + gdImageGif(im, out);
45 diff -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
56 +** Wrapper functions for this module.
59 +void gdImageBigGif(gdImagePtr im, FILE *outFile)
61 + gdIOCtx *out = gdNewFileCtx(outFile);
62 + gdImageBigGifCtx(im, out);
66 +void* gdImageBigGifPtr(gdImagePtr im, int *size)
69 + gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
70 + gdImageBigGifCtx(im, out);
71 + rv = gdDPExtractData(out,size);
76 +/* Code drawn from ppmtogif.c, from the pbmplus package
78 +** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
79 +** Lempel-Zim compression based on "compress".
81 +** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
83 +** Copyright (C) 1989 by Jef Poskanzer.
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
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.
96 +* Heavily modified by Mouse, 1998-02-12.
97 +* Remove LZW compression.
98 +* Added miGIF run length compression.
103 + * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
105 +typedef int code_int;
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);
116 +* static void char_init (void);
117 +* static void char_out (int c);
120 +/* Allows for reuse */
121 +static void init_statics(void);
123 +void gdImageBigGifCtx(gdImagePtr im, gdIOCtx *out)
125 + int interlace, transparent, BitsPerPixel;
127 + interlace = im->interlace;
128 + transparent = im->transparent;
130 + BitsPerPixel = colorstobpp(im->colorsTotal);
131 + /* Clear any old values in statics strewn through the GIF code */
133 + /* All set, let's do it. */
135 + out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
136 + im->red, im->green, im->blue, im);
140 +colorstobpp(int colors)
146 + else if ( colors <= 4 )
148 + else if ( colors <= 8 )
150 + else if ( colors <= 16 )
152 + else if ( colors <= 32 )
154 + else if ( colors <= 64 )
156 + else if ( colors <= 128 )
158 + else if ( colors <= 256 )
163 +/*****************************************************************************
165 + * GIFENCODE.C - GIF Image compression interface
167 + * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
168 + * BitsPerPixel, Red, Green, Blue, gdImagePtr )
170 + *****************************************************************************/
175 +static int Width, Height;
176 +static int curx, cury;
177 +static long CountDown;
178 +static int Pass = 0;
179 +static int Interlace;
182 + * Bump the 'curx' and 'cury' to point to the next pixel
188 + * Bump the current X position
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.
197 + if( curx == Width ) {
207 + if( cury >= Height ) {
215 + if( cury >= Height ) {
223 + if( cury >= Height ) {
238 + * Return the next pixel from the image
241 +GIFNextPixel(gdImagePtr im)
245 + if( CountDown == 0 )
250 + r = gdImageGetPixel(im, curx, cury);
260 +GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
263 + int RWidth, RHeight;
264 + int LeftOfs, TopOfs;
270 + Interlace = GInterlace;
272 + ColorMapSize = 1 << BitsPerPixel;
274 + RWidth = Width = GWidth;
275 + RHeight = Height = GHeight;
276 + LeftOfs = TopOfs = 0;
278 + Resolution = BitsPerPixel;
281 + * Calculate number of bits we are expecting
283 + CountDown = (long)Width * (long)Height;
286 + * Indicate which pass we are on (if interlace)
291 + * The initial code size
293 + if( BitsPerPixel <= 1 )
296 + InitCodeSize = BitsPerPixel;
299 + * Set up the current x and y position
304 + * Write the Magic header
306 + gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
309 + * Write out the screen width and height
311 + Putword( RWidth, fp );
312 + Putword( RHeight, fp );
315 + * Indicate that there is a global colour map
317 + B = 0x80; /* Yes, there is a color map */
320 + * OR in the resolution
322 + B |= (Resolution - 1) << 4;
325 + * OR in the Bits per Pixel
327 + B |= (BitsPerPixel - 1);
335 + * Write out the Background colour
337 + gdPutC( Background, fp );
340 + * Byte of 0's (future expansion)
345 + * Write out the Global Colour Map
347 + for( i=0; i<ColorMapSize; ++i ) {
348 + gdPutC( Red[i], fp );
349 + gdPutC( Green[i], fp );
350 + gdPutC( Blue[i], fp );
354 + * Write out extension for transparent colour index, if necessary.
356 + if ( Transparent >= 0 ) {
358 + gdPutC( 0xf9, fp );
363 + gdPutC( (unsigned char) Transparent, fp );
368 + * Write an Image separator
373 + * Write the Image header
376 + Putword( LeftOfs, fp );
377 + Putword( TopOfs, fp );
378 + Putword( Width, fp );
379 + Putword( Height, fp );
382 + * Write out whether or not the image is interlaced
385 + gdPutC( 0x40, fp );
387 + gdPutC( 0x00, fp );
390 + * Write out the initial code size
392 + gdPutC( InitCodeSize, fp );
395 + * Go and actually compress the data
397 + GIFcompress( InitCodeSize+1, fp, im, Background );
400 + * Write out a Zero-length packet (to end the series)
405 + * Write the GIF file terminator
410 +/* Write out a word to the GIF file */
412 +/*Putword(int w, gdIOCtx *fp) */
414 +/* fputc( w & 0xff, fp ); */
415 +/* fputc( (w / 256) & 0xff, fp ); */
420 +/*-----------------------------------------------------------------------
422 + * miGIF Compression - mouse and ivo's GIF-compatible compression
424 + * -run length encoding compression routines-
426 + * Copyright (C) 1998 Hutchison Avenue Software Corporation
427 + * http://www.hasc.com
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
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.
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.
453 + * mouse@rodents.montreal.qc.ca
454 + * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
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.
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;
482 +static gdIOCtx *ofile;
483 +static unsigned char oblock[256];
486 +/* Used only when debugging GIF compression code */
487 +/* #define DEBUGGING_ENVARS */
489 +#ifdef DEBUGGING_ENVARS
491 +static int verbose_set = 0;
493 +#define VERBOSE (verbose_set?verbose:set_verbose())
495 +static int set_verbose(void)
497 + verbose = !!getenv("GIF_VERBOSE");
509 +static const char *binformat(unsigned int v, int nbits)
511 + static char bufs[8][64];
512 + static int bhand = 0;
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++ = '.';
525 + return(&bufs[bhand][0]);
528 +static void write_block(void)
533 + { printf("write_block %d:",oblen);
534 + for (i=0;i<oblen;i++) printf(" %02x",oblock[i]);
537 + gdPutC(oblen,ofile);
538 + gdPutBuf(&oblock[0],oblen,ofile);
542 +static void block_out(unsigned char c)
544 + if (VERBOSE) printf("block_out %s\n",binformat(c,8));
545 + oblock[oblen++] = c;
546 + if (oblen >= 255) write_block();
549 +static void block_flush(void)
551 + if (VERBOSE) printf("block_flush\n");
552 + if (oblen > 0) write_block();
555 +static void output(int val)
557 + if (VERBOSE) printf("output %s [%s %d %d]\n",binformat(val,out_bits),binformat(obuf,obits),obits,out_bits);
558 + obuf |= val << obits;
561 + { block_out(obuf&0xff);
565 + if (VERBOSE) printf("output leaving [%s %d]\n",binformat(obuf,obits),obits);
568 +static void output_flush(void)
570 + if (VERBOSE) printf("output_flush\n");
571 + if (obits > 0) block_out(obuf);
575 +static void did_clear(void)
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;
586 +static void output_plain(int c)
588 + if (VERBOSE) printf("output_plain %s\n",binformat(c,out_bits));
592 + if (out_count >= out_bump)
594 + out_bump += 1 << (out_bits - 1);
596 + if (out_count >= out_clear)
597 + { output(code_clear);
602 +static unsigned int isqrt(unsigned int x)
607 + if (x < 2) return(x);
608 + for (v=x,r=1;v;v>>=2,r<<=1) ;
610 + { v = ((x / r) + r) / 2;
611 + if ((v == r) || (v == r+1)) return(r);
616 +static unsigned int compute_triangle_count(unsigned int count, unsigned int nrepcodes)
618 + unsigned int perrep;
622 + perrep = (nrepcodes * (nrepcodes+1)) / 2;
623 + while (count >= perrep)
624 + { cost += nrepcodes;
630 + while ((n*(n+1)) >= 2*count) n --;
631 + while ((n*(n+1)) < 2*count) n ++;
637 +static void max_out_clear(void)
639 + out_clear = max_ocodes;
642 +static void reset_out_clear(void)
644 + out_clear = out_clear_init;
645 + if (out_count >= out_clear)
646 + { output(code_clear);
651 +static void rl_flush_fromclear(int count)
655 + if (VERBOSE) printf("rl_flush_fromclear %d\n",count);
657 + rl_table_pixel = rl_pixel;
661 + { rl_table_max = 1;
662 + output_plain(rl_pixel);
665 + else if (count >= n)
666 + { rl_table_max = n;
667 + output_plain(rl_basecode+n-2);
670 + else if (count == 1)
672 + output_plain(rl_pixel);
677 + output_plain(rl_basecode+count-2);
680 + if (out_count == 0) n = 1; else n ++;
683 + if (VERBOSE) printf("rl_flush_fromclear leaving table_max=%d\n",rl_table_max);
686 +static void rl_flush_clearorrep(int count)
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);
695 + rl_flush_fromclear(count);
698 + { for (;count>0;count--) output_plain(rl_pixel);
702 +static void rl_flush_withtable(int count)
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);
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);
721 + rl_flush_fromclear(count);
725 + for (;repmax>0;repmax--) output_plain(rl_basecode+rl_table_max-2);
727 + { if (just_cleared)
728 + { rl_flush_fromclear(leftover);
730 + else if (leftover == 1)
731 + { output_plain(rl_pixel);
734 + { output_plain(rl_basecode+leftover-2);
740 +static void rl_flush(void)
742 + /* UNUSED int table_reps; */
743 + /* UNUSED int table_extra; */
745 + if (VERBOSE) printf("rl_flush [ %d %d\n",rl_count,rl_pixel);
747 + { output_plain(rl_pixel);
749 + if (VERBOSE) printf("rl_flush ]\n");
753 + { rl_flush_fromclear(rl_count);
755 + else if ((rl_table_max < 2) || (rl_table_pixel != rl_pixel))
756 + { rl_flush_clearorrep(rl_count);
759 + { rl_flush_withtable(rl_count);
761 + if (VERBOSE) printf("rl_flush ]\n");
765 +static void GIFcompress(int init_bits, gdIOCtx *outfile, gdImagePtr im, int background)
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");
784 + { out_clear_init = atoi(ocienv);
785 + if (VERBOSE) printf("[overriding out_clear_init to %d]\n",out_clear_init);
789 + out_bits_init = init_bits;
790 + max_ocodes = (1 << GIFBITS) - ((1 << (out_bits_init - 1)) + 3);
792 + output(code_clear);
795 + { c = GIFNextPixel(im);
796 + if ((rl_count > 0) && (c != rl_pixel)) rl_flush();
797 + if (c == EOF) break;
810 +/*-----------------------------------------------------------------------
812 + * End of miGIF section - See copyright notice at start of section.
814 + *-----------------------------------------------------------------------
817 +/******************************************************************************
819 + * GIF Specific routines
821 + ******************************************************************************/
824 + * Number of characters so far in this 'packet'
829 + * Set up the 'byte output' routine
841 + * Define the storage for the packet accumulator
844 +/* UNUSED static char accum[ 256 ]; */
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
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 +/* +-------------------------------------------------------------------+ */
872 diff -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 @@
879 -gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c)
880 +gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c)
885 + gdImageLine(im, p->x, p->y, p[n-1].x, p[n-1].y, c);
886 + gdImageOpenPolygon(im, p, n, c);
890 +gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c)
894 @@ -2711,7 +2721,6 @@
898 - gdImageLine (im, lx, ly, p[n - 1].x, p[n - 1].y, c);
899 for (i = 1; (i < n); i++)
902 diff -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
907 +#include <unistd.h> /* For unlink function */
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. */
915 +void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2);
918 +int main(int argc, char **argv)
920 + gdImagePtr im1, im2;
924 + fprintf(stderr, "Usage: gdcmpgif filename.gif filename.gif\n");
927 + in = fopen(argv[1], "rb");
929 + fprintf(stderr, "Input file does not exist!\n");
932 + im1 = gdImageCreateFromGif(in);
936 + fprintf(stderr, "Input is not in GIF format!\n");
940 + in = fopen(argv[2], "rb");
942 + fprintf(stderr, "Input file 2 does not exist!\n");
945 + im2 = gdImageCreateFromGif(in);
949 + fprintf(stderr, "Input 2 is not in GIF format!\n");
953 + CompareImages("gdcmpgif", im1, im2);
955 + gdImageDestroy(im1);
956 + gdImageDestroy(im2);
961 +void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2)
965 + cmpRes = gdImageCompare(im1, im2);
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);
972 + printf("%%%s: OK\n",msg);
976 + if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) {
977 + printf("-%s: INFO image sizes differ\n",msg);
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);
985 + if (cmpRes & GD_CMP_COLOR) {
986 + printf("-%s: INFO actual colours of pixels differ\n",msg);
991 diff -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
1001 +/* Used only when debugging GIF compression code */
1002 +/* #define DEBUGGING_ENVARS */
1004 +#ifdef DEBUGGING_ENVARS
1006 +static int verbose_set = 0;
1007 +static int verbose;
1008 +#define VERBOSE (verbose_set?verbose:set_verbose())
1010 +static int set_verbose(void)
1012 + verbose = !!getenv("GIF_VERBOSE");
1024 +#define MAXCOLORMAPSIZE 256
1033 +#define MAX_LWZ_BITS 12
1035 +#define INTERLACE 0x40
1036 +#define LOCALCOLORMAP 0x80
1037 +#define BitSet(byte, bit) (((byte) & (bit)) == (bit))
1039 +#define ReadOK(file,buffer,len) (gdGetBuf(buffer, len, file) != 0)
1041 +#define LM_to_uint(a,b) (((b)<<8)|(a))
1043 +/* We may eventually want to use this information, but def it out for now */
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;
1061 +} Gif89 = { -1, -1, -1, 0 };
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);
1069 +static void ReadImage (gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace); /*1.4//, int ignore); */
1073 +gdImagePtr gdImageCreateFromGifSource(gdSourcePtr inSource)
1075 + gdIOCtx *in = gdNewSSCtx(inSource, NULL);
1078 + im = gdImageCreateFromGifCtx(in);
1086 +gdImageCreateFromGif(FILE *fdFile)
1088 + gdIOCtx *fd = gdNewFileCtx(fdFile);
1089 + gdImagePtr im = 0;
1091 + im = gdImageCreateFromGifCtx(fd);
1099 +gdImageCreateFromGifPtr (int size, void *data)
1102 + gdIOCtx *in = gdNewDynamicCtxEx (size, data, 0);
1103 + im = gdImageCreateFromGifCtx (in);
1109 +gdImageCreateFromGifCtx(gdIOCtxPtr fd)
1111 +/* 1.4 int imageNumber; */
1113 + int ColorResolution;
1116 + int Transparent = (-1);
1117 + unsigned char buf[16];
1119 + unsigned char ColorMap[3][MAXCOLORMAPSIZE];
1120 + unsigned char localColorMap[3][MAXCOLORMAPSIZE];
1122 + int useGlobalColormap;
1125 + /*1.4//int imageCount = 0; */
1128 + gdImagePtr im = 0;
1129 + ZeroDataBlock = FALSE;
1131 + /*1.4//imageNumber = 1; */
1132 + if (! ReadOK(fd,buf,6)) {
1135 + if (strncmp((char *)buf,"GIF",3) != 0) {
1138 + strncpy(version, (char *)buf + 3, 3);
1139 + version[3] = '\0';
1141 + if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) {
1144 + if (! ReadOK(fd,buf,7)) {
1147 + BitPixel = 2<<(buf[4]&0x07);
1148 + ColorResolution = (int) (((buf[4]&0x70)>>3)+1);
1149 + Background = buf[5];
1150 + AspectRatio = buf[6];
1152 + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */
1153 + if (ReadColorMap(fd, BitPixel, ColorMap)) {
1158 + if (! ReadOK(fd,&c,1)) {
1161 + if (c == ';') { /* GIF terminator */
1165 + if (c == '!') { /* Extension */
1166 + if (! ReadOK(fd,&c,1)) {
1169 + DoExtension(fd, c, &Transparent);
1173 + if (c != ',') { /* Not a valid start character */
1177 + /*1.4//++imageCount; */
1179 + if (! ReadOK(fd,buf,9)) {
1183 + useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
1185 + bitPixel = 1<<((buf[8]&0x07)+1);
1187 + imw = LM_to_uint(buf[4],buf[5]);
1188 + imh = LM_to_uint(buf[6],buf[7]);
1189 + if (!(im = gdImageCreate(imw, imh))) {
1192 + im->interlace = BitSet(buf[8], INTERLACE);
1193 + if (! useGlobalColormap) {
1194 + if (ReadColorMap(fd, bitPixel, localColorMap)) {
1197 + ReadImage(im, fd, imw, imh, localColorMap,
1198 + BitSet(buf[8], INTERLACE));
1199 + /*1.4//imageCount != imageNumber); */
1201 + ReadImage(im, fd, imw, imh,
1203 + BitSet(buf[8], INTERLACE));
1204 + /*1.4//imageCount != imageNumber); */
1206 + if (Transparent != (-1)) {
1207 + gdImageColorTransparent(im, Transparent);
1213 + /* Terminator before any image was declared! */
1217 + /* Check for open colors at the end, so
1218 + we can reduce colorsTotal and ultimately
1220 + for (i=((im->colorsTotal-1)); (i>=0); i--) {
1221 + if (im->open[i]) {
1222 + im->colorsTotal--;
1231 +ReadColorMap(gdIOCtx *fd, int number, unsigned char (*buffer)[256])
1234 + unsigned char rgb[3];
1237 + for (i = 0; i < number; ++i) {
1238 + if (! ReadOK(fd, rgb, sizeof(rgb))) {
1241 + buffer[CM_RED][i] = rgb[0] ;
1242 + buffer[CM_GREEN][i] = rgb[1] ;
1243 + buffer[CM_BLUE][i] = rgb[2] ;
1251 +DoExtension(gdIOCtx *fd, int label, int *Transparent)
1253 + static unsigned char buf[256];
1256 + case 0xf9: /* Graphic Control Extension */
1257 + (void) GetDataBlock(fd, (unsigned char*) buf);
1258 + Gif89.disposal = (buf[0] >> 2) & 0x7;
1259 + Gif89.inputFlag = (buf[0] >> 1) & 0x1;
1260 + Gif89.delayTime = LM_to_uint(buf[1],buf[2]);
1261 + if ((buf[0] & 0x1) != 0)
1262 + *Transparent = buf[3];
1264 + while (GetDataBlock(fd, (unsigned char*) buf) != 0)
1270 + while (GetDataBlock(fd, (unsigned char*) buf) != 0)
1277 +GetDataBlock_(gdIOCtx *fd, unsigned char *buf)
1279 + unsigned char count;
1281 + if (! ReadOK(fd,&count,1)) {
1285 + ZeroDataBlock = count == 0;
1287 + if ((count != 0) && (! ReadOK(fd, buf, count))) {
1295 +GetDataBlock(gdIOCtx *fd, unsigned char *buf)
1300 + rv = GetDataBlock_(fd,buf);
1302 + { printf("[GetDataBlock returning %d",rv);
1305 + for (i=0;i<rv;i++) printf(" %02x",buf[i]);
1313 +GetCode_(gdIOCtx *fd, int code_size, int flag)
1315 + static unsigned char buf[280];
1316 + static int curbit, lastbit, done, last_byte;
1318 + unsigned char count;
1327 + if ( (curbit+code_size) >= lastbit) {
1329 + if (curbit >= lastbit) {
1334 + buf[0] = buf[last_byte-2];
1335 + buf[1] = buf[last_byte-1];
1337 + if ((count = GetDataBlock(fd, &buf[2])) == 0)
1340 + last_byte = 2 + count;
1341 + curbit = (curbit - lastbit) + 16;
1342 + lastbit = (2+count)*8 ;
1346 + for (i = curbit, j = 0; j < code_size; ++i, ++j)
1347 + ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
1349 + curbit += code_size;
1354 +GetCode(gdIOCtx *fd, int code_size, int flag)
1358 + rv = GetCode_(fd,code_size,flag);
1359 + if (VERBOSE) printf("[GetCode(,%d,%d) returning %d]\n",code_size,flag,rv);
1363 +#define STACK_SIZE ((1<<(MAX_LWZ_BITS))*2)
1365 +LWZReadByte_(gdIOCtx *fd, int flag, int input_code_size)
1367 + static int fresh = FALSE;
1369 + static int code_size, set_code_size;
1370 + static int max_code, max_code_size;
1371 + static int firstcode, oldcode;
1372 + static int clear_code, end_code;
1373 + static int table[2][(1<< MAX_LWZ_BITS)];
1374 + static int stack[STACK_SIZE], *sp;
1378 + set_code_size = input_code_size;
1379 + code_size = set_code_size+1;
1380 + clear_code = 1 << set_code_size ;
1381 + end_code = clear_code + 1;
1382 + max_code_size = 2*clear_code;
1383 + max_code = clear_code+2;
1385 + GetCode(fd, 0, TRUE);
1389 + for (i = 0; i < clear_code; ++i) {
1393 + for (; i < (1<<MAX_LWZ_BITS); ++i)
1394 + table[0][i] = table[1][0] = 0;
1399 + } else if (fresh) {
1402 + firstcode = oldcode =
1403 + GetCode(fd, code_size, FALSE);
1404 + } while (firstcode == clear_code);
1411 + while ((code = GetCode(fd, code_size, FALSE)) >= 0) {
1412 + if (code == clear_code) {
1413 + for (i = 0; i < clear_code; ++i) {
1417 + for (; i < (1<<MAX_LWZ_BITS); ++i)
1418 + table[0][i] = table[1][i] = 0;
1419 + code_size = set_code_size+1;
1420 + max_code_size = 2*clear_code;
1421 + max_code = clear_code+2;
1423 + firstcode = oldcode =
1424 + GetCode(fd, code_size, FALSE);
1426 + } else if (code == end_code) {
1428 + unsigned char buf[260];
1430 + if (ZeroDataBlock)
1433 + while ((count = GetDataBlock(fd, buf)) > 0)
1442 + if (sp == (stack + STACK_SIZE)) {
1443 + /* Bad compressed data stream */
1447 + if (code >= max_code) {
1448 + *sp++ = firstcode;
1452 + while (code >= clear_code) {
1453 + if (sp == (stack + STACK_SIZE)) {
1454 + /* Bad compressed data stream */
1457 + *sp++ = table[1][code];
1458 + if (code == table[0][code]) {
1461 + code = table[0][code];
1464 + *sp++ = firstcode = table[1][code];
1466 + if ((code = max_code) <(1<<MAX_LWZ_BITS)) {
1467 + table[0][code] = oldcode;
1468 + table[1][code] = firstcode;
1470 + if ((max_code >= max_code_size) &&
1471 + (max_code_size < (1<<MAX_LWZ_BITS))) {
1472 + max_code_size *= 2;
1486 +LWZReadByte(gdIOCtx *fd, int flag, int input_code_size)
1490 + rv = LWZReadByte_(fd,flag,input_code_size);
1491 + if (VERBOSE) printf("[LWZReadByte(,%d,%d) returning %d]\n",flag,input_code_size,rv);
1496 +ReadImage(gdImagePtr im, gdIOCtx *fd, int len, int height, unsigned char (*cmap)[256], int interlace) /*1.4//, int ignore) */
1500 + int xpos = 0, ypos = 0, pass = 0;
1502 + /* Stash the color map into the image */
1503 + for (i=0; (i<gdMaxColors); i++) {
1504 + im->red[i] = cmap[CM_RED][i];
1505 + im->green[i] = cmap[CM_GREEN][i];
1506 + im->blue[i] = cmap[CM_BLUE][i];
1509 + /* Many (perhaps most) of these colors will remain marked open. */
1510 + im->colorsTotal = gdMaxColors;
1512 + ** Initialize the Compression routines
1514 + if (! ReadOK(fd,&c,1)) {
1517 + if (LWZReadByte(fd, TRUE, c) < 0) {
1522 + ** If this is an "uninteresting picture" ignore it.
1523 + ** REMOVED For 1.4
1525 + /*if (ignore) { */
1526 + /* while (LWZReadByte(fd, FALSE, c) >= 0) */
1531 + while ((v = LWZReadByte(fd,FALSE,c)) >= 0 ) {
1532 + /* This how we recognize which colors are actually used. */
1533 + if (im->open[v]) {
1536 + gdImageSetPixel(im, xpos, ypos, v);
1538 + if (xpos == len) {
1551 + if (ypos >= height) {
1568 + if (ypos >= height)
1573 + if (LWZReadByte(fd,FALSE,c)>=0) {
1574 + /* Ignore extra */
1578 diff -Nur gd-2.0.17.orig/gd_gif_out.c gd-2.0.17/gd_gif_out.c
1579 --- gd-2.0.17.orig/gd_gif_out.c 1970-01-01 01:00:00.000000000 +0100
1580 +++ gd-2.0.17/gd_gif_out.c 2003-12-26 15:35:52.294570064 +0100
1584 +#include <string.h>
1585 +#include <stdlib.h>
1589 +** Wrapper functions for GIF output.
1592 +#define LZW_LICENCED
1594 +void gdImageGifToSink(gdImagePtr im, gdSinkPtr outSink)
1596 + gdIOCtx *out = gdNewSSCtx(NULL,outSink);
1597 + gdImageGifCtx(im, out);
1598 + out->gd_free(out);
1601 +void gdImageGifCtx(gdImagePtr im, gdIOCtx *out)
1603 +#ifdef LZW_LICENCED
1604 + gdImageLzwCtx(im, out);
1606 + gdImageBigGifCtx(im, out);
1610 +void gdImageGif(gdImagePtr im, FILE *outFile)
1612 +#ifdef LZW_LICENCED
1613 + gdImageLzw(im, outFile);
1615 + gdImageBigGif(im, outFile);
1619 +void* gdImageGifPtr(gdImagePtr im, int *size)
1621 +#ifdef LZW_LICENCED
1622 + return gdImageLzwPtr(im, size);
1624 + return gdImageBigGifPtr(im, size);
1628 diff -Nur gd-2.0.19.orig/gd.h gd-2.0.19/gd.h
1629 --- gd-2.0.19.orig/gd.h 2003-12-24 20:55:14.000000000 +0100
1630 +++ gd-2.0.19/gd.h 2003-12-26 15:35:52.276572800 +0100
1631 @@ -240,6 +240,11 @@
1633 BGD_EXPORT gdImagePtr gdImageCreateFromPngSource (gdSourcePtr in);
1635 + BGD_EXPORT gdImagePtr gdImageCreateFromGif (FILE *fd);
1636 + BGD_EXPORT gdImagePtr gdImageCreateFromGifCtx (gdIOCtxPtr in);
1637 + BGD_EXPORT gdImagePtr gdImageCreateFromGifPtr (int size, void *data);
1638 + BGD_EXPORT gdImagePtr gdImageCreateFromGifSource (gdSourcePtr in);
1640 BGD_EXPORT gdImagePtr gdImageCreateFromGd (FILE * in);
1641 BGD_EXPORT gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in);
1644 gdPoint, *gdPointPtr;
1646 BGD_EXPORT void gdImagePolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1647 + BGD_EXPORT void gdImageOpenPolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1648 BGD_EXPORT void gdImageFilledPolygon (gdImagePtr im, gdPointPtr p, int n, int c);
1650 /* These functions still work with truecolor images,
1651 @@ -455,6 +461,14 @@
1652 /* Best to free this memory with gdFree(), not free() */
1653 void *gdImageJpegPtr (gdImagePtr im, int *size, int quality);
1655 +BGD_EXPORT void gdImageLzw(gdImagePtr im, FILE *out);
1656 +BGD_EXPORT void* gdImageLzwPtr(gdImagePtr im, int *size);
1657 +BGD_EXPORT void gdImageLzwCtx(gdImagePtr im, gdIOCtxPtr out);
1659 +BGD_EXPORT void gdImageBigGif(gdImagePtr im, FILE *out);
1660 +BGD_EXPORT void* gdImageBigGifPtr(gdImagePtr im, int *size);
1661 +BGD_EXPORT void gdImageBigGifCtx(gdImagePtr im, gdIOCtxPtr out);
1663 /* A custom data sink. For backwards compatibility. Use
1665 /* The sink function must return -1 on error, otherwise the number
1666 @@ -469,6 +483,11 @@
1668 BGD_EXPORT void gdImagePngToSink (gdImagePtr im, gdSinkPtr out);
1670 + BGD_EXPORT void gdImageGif (gdImagePtr im, FILE *out);
1671 + BGD_EXPORT void* gdImageGifPtr (gdImagePtr im, int *size);
1672 + BGD_EXPORT void gdImageGifCtx (gdImagePtr im, gdIOCtxPtr out);
1673 + BGD_EXPORT void gdImageGifToSink (gdImagePtr im, gdSinkPtr out);
1675 BGD_EXPORT void gdImageGd (gdImagePtr im, FILE * out);
1676 BGD_EXPORT void gdImageGd2 (gdImagePtr im, FILE * out, int cs, int fmt);
1678 diff -Nur gd-2.0.17.orig/gd_lzw_out.c gd-2.0.17/gd_lzw_out.c
1679 --- gd-2.0.17.orig/gd_lzw_out.c 1970-01-01 01:00:00.000000000 +0100
1680 +++ gd-2.0.17/gd_lzw_out.c 2003-12-26 15:35:52.300569152 +0100
1682 +#include <malloc.h>
1685 +#include <string.h>
1686 +#include <stdlib.h>
1689 +/* Code drawn from ppmtogif.c, from the pbmplus package
1691 +** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A
1692 +** Lempel-Zim compression based on "compress".
1694 +** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl>
1696 +** Copyright (C) 1989 by Jef Poskanzer.
1698 +** Permission to use, copy, modify, and distribute this software and its
1699 +** documentation for any purpose and without fee is hereby granted, provided
1700 +** that the above copyright notice appear in all copies and that both that
1701 +** copyright notice and this permission notice appear in supporting
1702 +** documentation. This software is provided "as is" without express or
1703 +** implied warranty.
1705 +** The Graphics Interchange Format(c) is the Copyright property of
1706 +** CompuServe Incorporated. GIF(sm) is a Service Mark property of
1707 +** CompuServe Incorporated.
1711 + * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
1713 +typedef int code_int;
1715 +#ifdef SIGNED_COMPARE_SLOW
1716 +typedef unsigned long int count_int;
1717 +typedef unsigned short int count_short;
1718 +#else /*SIGNED_COMPARE_SLOW*/
1719 +typedef long int count_int;
1720 +#endif /*SIGNED_COMPARE_SLOW*/
1722 +static int colorstobpp(int colors);
1723 +static void BumpPixel (void);
1724 +static int GIFNextPixel (gdImagePtr im);
1725 +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);
1726 +/*static void Putword (int w, gdIOCtx *fp); */
1727 +static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im);
1728 +static void output (code_int code);
1729 +static void cl_block (void);
1730 +static void cl_hash (register count_int hsize);
1731 +static void char_init (void);
1732 +static void char_out (int c);
1733 +static void flush_char (void);
1734 +/* Allows for reuse */
1735 +static void init_statics(void);
1737 +void gdImageLzwCtx(gdImagePtr im, gdIOCtx *out)
1739 + int interlace, transparent, BitsPerPixel;
1741 + interlace = im->interlace;
1742 + transparent = im->transparent;
1744 + BitsPerPixel = colorstobpp(im->colorsTotal);
1745 + /* Clear any old values in statics strewn through the GIF code */
1747 + /* All set, let's do it. */
1749 + out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel,
1750 + im->red, im->green, im->blue, im);
1753 +void gdImageLzw(gdImagePtr im, FILE *outFile)
1755 + gdIOCtx *out = gdNewFileCtx(outFile);
1756 + gdImageLzwCtx(im, out);
1757 + out->gd_free(out);
1760 +void* gdImageLzwPtr(gdImagePtr im, int *size)
1763 + gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
1764 + gdImageLzwCtx(im, out);
1765 + rv = gdDPExtractData(out,size);
1766 + out->gd_free(out);
1773 +colorstobpp(int colors)
1777 + if ( colors <= 2 )
1779 + else if ( colors <= 4 )
1781 + else if ( colors <= 8 )
1783 + else if ( colors <= 16 )
1785 + else if ( colors <= 32 )
1787 + else if ( colors <= 64 )
1789 + else if ( colors <= 128 )
1791 + else if ( colors <= 256 )
1796 +/*****************************************************************************
1798 + * GIFENCODE.C - GIF Image compression interface
1800 + * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent,
1801 + * BitsPerPixel, Red, Green, Blue, gdImagePtr )
1803 + *****************************************************************************/
1808 +static int Width, Height;
1809 +static int curx, cury;
1810 +static long CountDown;
1811 +static int Pass = 0;
1812 +static int Interlace;
1815 + * Bump the 'curx' and 'cury' to point to the next pixel
1821 + * Bump the current X position
1826 + * If we are at the end of a scan line, set curx back to the beginning
1827 + * If we are interlaced, bump the cury to the appropriate spot,
1828 + * otherwise, just increment it.
1830 + if( curx == Width ) {
1840 + if( cury >= Height ) {
1848 + if( cury >= Height ) {
1856 + if( cury >= Height ) {
1871 + * Return the next pixel from the image
1874 +GIFNextPixel(gdImagePtr im)
1878 + if( CountDown == 0 )
1883 + r = gdImageGetPixel(im, curx, cury);
1893 +GIFEncode(gdIOCtx *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
1896 + int RWidth, RHeight;
1897 + int LeftOfs, TopOfs;
1903 + Interlace = GInterlace;
1905 + ColorMapSize = 1 << BitsPerPixel;
1907 + RWidth = Width = GWidth;
1908 + RHeight = Height = GHeight;
1909 + LeftOfs = TopOfs = 0;
1911 + Resolution = BitsPerPixel;
1914 + * Calculate number of bits we are expecting
1916 + CountDown = (long)Width * (long)Height;
1919 + * Indicate which pass we are on (if interlace)
1924 + * The initial code size
1926 + if( BitsPerPixel <= 1 )
1929 + InitCodeSize = BitsPerPixel;
1932 + * Set up the current x and y position
1937 + * Write the Magic header
1939 + gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
1942 + * Write out the screen width and height
1944 + Putword( RWidth, fp );
1945 + Putword( RHeight, fp );
1948 + * Indicate that there is a global colour map
1950 + B = 0x80; /* Yes, there is a color map */
1953 + * OR in the resolution
1955 + B |= (Resolution - 1) << 5;
1958 + * OR in the Bits per Pixel
1960 + B |= (BitsPerPixel - 1);
1968 + * Write out the Background colour
1970 + gdPutC( Background, fp );
1973 + * Byte of 0's (future expansion)
1978 + * Write out the Global Colour Map
1980 + for( i=0; i<ColorMapSize; ++i ) {
1981 + gdPutC( Red[i], fp );
1982 + gdPutC( Green[i], fp );
1983 + gdPutC( Blue[i], fp );
1987 + * Write out extension for transparent colour index, if necessary.
1989 + if ( Transparent >= 0 ) {
1990 + gdPutC( '!', fp );
1991 + gdPutC( 0xf9, fp );
1996 + gdPutC( (unsigned char) Transparent, fp );
2001 + * Write an Image separator
2003 + gdPutC( ',', fp );
2006 + * Write the Image header
2009 + Putword( LeftOfs, fp );
2010 + Putword( TopOfs, fp );
2011 + Putword( Width, fp );
2012 + Putword( Height, fp );
2015 + * Write out whether or not the image is interlaced
2018 + gdPutC( 0x40, fp );
2020 + gdPutC( 0x00, fp );
2023 + * Write out the initial code size
2025 + gdPutC( InitCodeSize, fp );
2028 + * Go and actually compress the data
2030 + compress( InitCodeSize+1, fp, im );
2033 + * Write out a Zero-length packet (to end the series)
2038 + * Write the GIF file terminator
2040 + gdPutC( ';', fp );
2044 +/* * Write out a word to the GIF file */
2047 +/*Putword(int w, FILE *fp) */
2049 +/* fputc( w & 0xff, fp ); */
2050 +/* fputc( (w / 256) & 0xff, fp ); */
2054 +/***************************************************************************
2056 + * GIFCOMPR.C - GIF Image compression routines
2058 + * Lempel-Ziv compression based on 'compress'. GIF modifications by
2059 + * David Rowley (mgardi@watdcsu.waterloo.edu)
2061 + ***************************************************************************/
2069 +#define HSIZE 5003 /* 80% occupancy */
2072 + typedef char char_type;
2074 + typedef unsigned char char_type;
2075 +#endif /*NO_UCHAR*/
2079 + * GIF Image compression - modified 'compress'
2081 + * Based on: compress.c - File compression ala IEEE Computer, June 1984.
2083 + * By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
2084 + * Jim McKie (decvax!mcvax!jim)
2085 + * Steve Davies (decvax!vax135!petsd!peora!srd)
2086 + * Ken Turkowski (decvax!decwrl!turtlevax!ken)
2087 + * James A. Woods (decvax!ihnp4!ames!jaw)
2088 + * Joe Orost (decvax!vax135!petsd!joe)
2093 +#define ARGVAL() (*++(*argv) || (--argc && *++argv))
2095 +static int n_bits; /* number of bits/code */
2096 +static int maxbits = GIFBITS; /* user settable max # bits/code */
2097 +static code_int maxcode; /* maximum code, given n_bits */
2098 +static code_int maxmaxcode = (code_int)1 << GIFBITS; /* should NEVER generate this code */
2099 +#ifdef COMPATIBLE /* But wrong! */
2100 +# define MAXCODE(n_bits) ((code_int) 1 << (n_bits) - 1)
2101 +#else /*COMPATIBLE*/
2102 +# define MAXCODE(n_bits) (((code_int) 1 << (n_bits)) - 1)
2103 +#endif /*COMPATIBLE*/
2105 +static count_int htab [HSIZE];
2106 +static unsigned short codetab [HSIZE];
2107 +#define HashTabOf(i) htab[i]
2108 +#define CodeTabOf(i) codetab[i]
2110 +static code_int hsize = HSIZE; /* for dynamic table sizing */
2113 + * To save much memory, we overlay the table used by compress() with those
2114 + * used by decompress(). The tab_prefix table is the same size and type
2115 + * as the codetab. The tab_suffix table needs 2**GIFBITS characters. We
2116 + * get this from the beginning of htab. The output stack uses the rest
2117 + * of htab, and contains characters. There is plenty of room for any
2118 + * possible stack (stack used to be 8000 characters).
2121 +#define tab_prefixof(i) CodeTabOf(i)
2122 +#define tab_suffixof(i) ((char_type*)(htab))[i]
2123 +#define de_stack ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
2125 +static code_int free_ent = 0; /* first unused entry */
2128 + * block compression parameters -- after all codes are used up,
2129 + * and compression rate changes, start over.
2131 +static int clear_flg = 0;
2134 +static long int in_count = 1; /* length of input */
2135 +static long int out_count = 0; /* # of codes output (for debugging) */
2138 + * compress stdin to stdout
2140 + * Algorithm: use open addressing double hashing (no chaining) on the
2141 + * prefix code / next character combination. We do a variant of Knuth's
2142 + * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
2143 + * secondary probe. Here, the modular division first probe is gives way
2144 + * to a faster exclusive-or manipulation. Also do block compression with
2145 + * an adaptive reset, whereby the code table is cleared when the compression
2146 + * ratio decreases, but after the table fills. The variable-length output
2147 + * codes are re-sized at this point, and a special CLEAR code is generated
2148 + * for the decompressor. Late addition: construct the table according to
2149 + * file size for noticeable speed improvement on small files. Please direct
2150 + * questions about this implementation to ames!jaw.
2153 +static int g_init_bits;
2154 +static gdIOCtx* g_outfile;
2156 +static int ClearCode;
2157 +static int EOFCode;
2160 +compress(int init_bits, gdIOCtx *outfile, gdImagePtr im)
2162 + register long fcode;
2163 + register code_int i /* = 0 */;
2165 + register code_int ent;
2166 + register code_int disp;
2167 + register code_int hsize_reg;
2168 + register int hshift;
2171 + * Set up the globals: g_init_bits - initial number of bits
2172 + * g_outfile - pointer to output file
2174 + g_init_bits = init_bits;
2175 + g_outfile = outfile;
2178 + * Set up the necessary values
2184 + maxcode = MAXCODE(n_bits = g_init_bits);
2186 + ClearCode = (1 << (init_bits - 1));
2187 + EOFCode = ClearCode + 1;
2188 + free_ent = ClearCode + 2;
2192 + ent = GIFNextPixel( im );
2195 + for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
2197 + hshift = 8 - hshift; /* set hash code range bound */
2199 + hsize_reg = hsize;
2200 + cl_hash( (count_int) hsize_reg); /* clear hash table */
2202 + output( (code_int)ClearCode );
2204 +#ifdef SIGNED_COMPARE_SLOW
2205 + while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {
2206 +#else /*SIGNED_COMPARE_SLOW*/
2207 + while ( (c = GIFNextPixel( im )) != EOF ) { /* } */
2208 +#endif /*SIGNED_COMPARE_SLOW*/
2212 + fcode = (long) (((long) c << maxbits) + ent);
2213 + i = (((code_int)c << hshift) ^ ent); /* xor hashing */
2215 + if ( HashTabOf (i) == fcode ) {
2216 + ent = CodeTabOf (i);
2218 + } else if ( (long)HashTabOf (i) < 0 ) /* empty slot */
2220 + disp = hsize_reg - i; /* secondary hash (after G. Knott) */
2224 + if ( (i -= disp) < 0 )
2227 + if ( HashTabOf (i) == fcode ) {
2228 + ent = CodeTabOf (i);
2231 + if ( (long)HashTabOf (i) > 0 )
2234 + output ( (code_int) ent );
2237 +#ifdef SIGNED_COMPARE_SLOW
2238 + if ( (unsigned) free_ent < (unsigned) maxmaxcode) {
2239 +#else /*SIGNED_COMPARE_SLOW*/
2240 + if ( free_ent < maxmaxcode ) { /* } */
2241 +#endif /*SIGNED_COMPARE_SLOW*/
2242 + CodeTabOf (i) = free_ent++; /* code -> hashtable */
2243 + HashTabOf (i) = fcode;
2248 + * Put out the final code.
2250 + output( (code_int)ent );
2252 + output( (code_int) EOFCode );
2255 +/*****************************************************************
2258 + * Output the given code.
2260 + * code: A n_bits-bit integer. If == -1, then EOF. This assumes
2261 + * that n_bits =< (long)wordsize - 1.
2263 + * Outputs code to the file.
2265 + * Chars are 8 bits long.
2267 + * Maintain a GIFBITS character long buffer (so that 8 codes will
2268 + * fit in it exactly). Use the VAX insv instruction to insert each
2269 + * code in turn. When the buffer fills up empty it and start over.
2272 +static unsigned long cur_accum = 0;
2273 +static int cur_bits = 0;
2275 +static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
2276 + 0x001F, 0x003F, 0x007F, 0x00FF,
2277 + 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
2278 + 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
2281 +output(code_int code)
2283 + cur_accum &= masks[ cur_bits ];
2285 + if( cur_bits > 0 )
2286 + cur_accum |= ((long)code << cur_bits);
2290 + cur_bits += n_bits;
2292 + while( cur_bits >= 8 ) {
2293 + char_out( (unsigned int)(cur_accum & 0xff) );
2299 + * If the next entry is going to be too big for the code size,
2300 + * then increase it, if possible.
2302 + if ( free_ent > maxcode || clear_flg ) {
2306 + maxcode = MAXCODE (n_bits = g_init_bits);
2312 + if ( n_bits == maxbits )
2313 + maxcode = maxmaxcode;
2315 + maxcode = MAXCODE(n_bits);
2319 + if( code == EOFCode ) {
2321 + * At EOF, write the rest of the buffer.
2323 + while( cur_bits > 0 ) {
2324 + char_out( (unsigned int)(cur_accum & 0xff) );
2331 +/* fflush( g_outfile ); */
2333 +/* if( ferror( g_outfile ) ) */
2339 + * Clear out the hash table
2342 +cl_block (void) /* table clear for block compress */
2345 + cl_hash ( (count_int) hsize );
2346 + free_ent = ClearCode + 2;
2349 + output( (code_int)ClearCode );
2353 +cl_hash(register count_int hsize) /* reset code table */
2357 + register count_int *htab_p = htab+hsize;
2360 + register long m1 = -1;
2363 + do { /* might use Sys V memset(3) here */
2364 + *(htab_p-16) = m1;
2365 + *(htab_p-15) = m1;
2366 + *(htab_p-14) = m1;
2367 + *(htab_p-13) = m1;
2368 + *(htab_p-12) = m1;
2369 + *(htab_p-11) = m1;
2370 + *(htab_p-10) = m1;
2381 + } while ((i -= 16) >= 0);
2383 + for ( i += 16; i > 0; --i )
2387 +/******************************************************************************
2389 + * GIF Specific routines
2391 + ******************************************************************************/
2394 + * Number of characters so far in this 'packet'
2396 +static int a_count;
2399 + * Set up the 'byte output' routine
2408 + * Define the storage for the packet accumulator
2410 +static char accum[ 256 ];
2413 + * Add a character to the end of the current packet, and if it is 254
2414 + * characters, flush the packet to disk.
2419 + accum[ a_count++ ] = c;
2420 + if( a_count >= 254 )
2425 + * Flush the packet to disk, and reset the accumulator
2430 + if( a_count > 0 ) {
2431 + gdPutC( a_count, g_outfile );
2432 + gdPutBuf( accum, a_count, g_outfile );
2437 +static void init_statics(void) {
2438 + /* Some of these are properly initialized later. What I'm doing
2439 + here is making sure code that depends on C's initialization
2440 + of statics doesn't break when the code gets called more
2463 + maxbits = GIFBITS;
2465 + maxmaxcode = (code_int)1 << GIFBITS;
2469 +/* +-------------------------------------------------------------------+ */
2470 +/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */
2471 +/* | Permission to use, copy, modify, and distribute this software | */
2472 +/* | and its documentation for any purpose and without fee is hereby | */
2473 +/* | granted, provided that the above copyright notice appear in all | */
2474 +/* | copies and that both that copyright notice and this permission | */
2475 +/* | notice appear in supporting documentation. This software is | */
2476 +/* | provided "as is" without express or implied warranty. | */
2477 +/* +-------------------------------------------------------------------+ */
2478 diff -Nur gd-2.0.17.orig/gdtest.c gd-2.0.17/gdtest.c
2479 --- gd-2.0.17.orig/gdtest.c 2003-03-29 16:46:35.000000000 +0100
2480 +++ gd-2.0.17/gdtest.c 2003-12-26 15:35:52.313567176 +0100
2482 CompareImages ("GD->PNG ptr->GD", ref, im2);
2484 gdImageDestroy (im2);
2487 + /* Send to GIF File then Ptr */
2489 + sprintf(of, "%s.gif", argv[1]);
2490 + out = fopen(of, "wb");
2491 + gdImageGif(im, out);
2494 + in = fopen(of, "rb");
2496 + fprintf(stderr, "GIF Output file does not exist!\n");
2499 + im2 = gdImageCreateFromGif(in);
2502 + CompareImages("GD->GIF File->GD", ref, im2);
2504 + gdImageDestroy(im2);
2507 + ** Test gdImageCreateFromGifSource
2510 + in = fopen(of, "rb");
2514 + fprintf (stderr, "GD Source: ERROR - GD Source input file does not exist - Sink may have failed!\n");
2517 + imgsrc.source = freadWrapper;
2518 + imgsrc.context = in;
2519 + im2 = gdImageCreateFromGifSource(&imgsrc);
2522 + if (im2 == NULL) {
2523 + printf("GD Source (GIF): ERROR Null returned by gdImageCreateFromGifSource\n");
2525 + CompareImages("GD Source (GIF)", ref, im2);
2526 + gdImageDestroy(im2);
2531 + iptr = gdImageGifPtr(im,&sz);
2532 + im2 = gdImageCreateFromGifPtr(sz,iptr);
2535 + CompareImages("GD->GIF ptr->GD", ref, im2);
2537 + gdImageDestroy(im2);
2540 /* Send to GD2 File then Ptr */
2542 gdImageDestroy (im2);
2548 /* Test Extraction */
2550 @@ -277,6 +328,10 @@
2551 printf ("[Merged Image has %d colours]\n", im2->colorsTotal);
2552 CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3);
2554 + out = fopen ("test/gdtest_merge_out.png", "wb");
2555 + gdImagePng(im2, out);
2558 gdImageDestroy (im2);
2559 gdImageDestroy (im3);
2561 diff -Nur gd-2.0.17.orig/gdtestft.c gd-2.0.17/gdtestft.c
2562 --- gd-2.0.17.orig/gdtestft.c 2003-03-29 16:46:35.000000000 +0100
2563 +++ gd-2.0.17/gdtestft.c 2003-12-26 15:35:52.316566720 +0100
2565 #define MAXY(x) MAX4(x[1],x[3],x[5],x[7])
2566 #define MINY(x) MIN4(x[1],x[3],x[5],x[7])
2568 +void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2);
2571 main (int argc, char *argv[])
2573 diff -Nur gd-2.0.17.orig/giftogd2.c gd-2.0.17/giftogd2.c
2574 --- gd-2.0.17.orig/giftogd2.c 1970-01-01 01:00:00.000000000 +0100
2575 +++ gd-2.0.17/giftogd2.c 2003-12-26 15:35:52.319566264 +0100
2578 +#include <stdlib.h>
2582 +/* A short program which converts a .gif file into a .gd file, for
2583 + your convenience in creating images on the fly from a
2584 + basis image that must be loaded quickly. The .gd format
2585 + is not intended to be a general-purpose format. */
2587 +int main(int argc, char **argv)
2594 + fprintf(stderr, "Usage: giftogd2 filename.gif filename.gd2 cs fmt\n");
2595 + fprintf(stderr, " where cs is the chunk size\n");
2596 + fprintf(stderr, " fmt is 1 for raw, 2 for compressed\n");
2599 + in = fopen(argv[1], "rb");
2601 + fprintf(stderr, "Input file does not exist!\n");
2604 + im = gdImageCreateFromGif(in);
2607 + fprintf(stderr, "Input is not in GIF format!\n");
2610 + out = fopen(argv[2], "wb");
2612 + fprintf(stderr, "Output file cannot be written to!\n");
2613 + gdImageDestroy(im);
2616 + cs = atoi(argv[3]);
2617 + fmt = atoi(argv[4]);
2618 + gdImageGd2(im, out, cs, fmt);
2620 + gdImageDestroy(im);
2625 diff -Nur gd-2.0.21.orig/index.html gd-2.0.21/index.html
2626 --- gd-2.0.21.orig/index.html 2003-12-25 17:43:52.000000000 +0100
2627 +++ gd-2.0.21/index.html 2003-12-26 15:38:31.022439760 +0100
2629 more compatible with the major Web browsers than even PNG is. WBMP is
2630 intended for wireless devices (not regular web browsers). Old
2631 code will need modification to call gdImagePng or gdImageJpeg instead
2632 -of gdImageGif. <strong>Please do not ask us to send you the old GIF
2635 +Note: The version at this site also supports GIF format, for those people
2636 +who have not yet managed to move away from GIFs.
2638 +<strong>Please do not ask the original author to send you the old GIF
2639 version of GD.</strong> Yes, Unisys still holds a patent on the LZW compression
2640 algorithm in some countries. The best
2641 solution is to move to legally unencumbered, well-compressed,
2642 @@ -117,6 +122,18 @@
2643 Portions relating to WBMP copyright 2000, 2001, 2002 Maurice Szmurlo and Johan Van
2646 +GIF decompression code copyright 1990, 1991, 1993, by David Koblas
2647 +(koblas@netcom.com).
2649 +Non-LZW-based GIF compression code copyright 1998, by Hutchison Avenue
2650 +Software Corporation (<a href="http://www.hasc.com">http://www.hasc.com/</a>,
2653 +LZW-based GIF compression code David Rowley.
2654 +Obtaining a license for the Unisys LZW compression patent is
2655 +entirely between the user and Unisys. The authors of gd can provide
2656 +NO assistance in this matter.
2658 <strong>Permission has been granted to copy, distribute and modify gd in any
2659 context without fee, including a commercial application, provided that this notice
2660 is present in user-accessible supporting documentation.</strong>
2661 @@ -202,6 +219,25 @@
2663 <li><a href="http://martin.gleeson.com/fly/">fly</a>, by Martin Gleeson
2665 +<P><A NAME="gifpatch"><H3>What's new in the patched version?</H3></A>
2667 +This version reinstates GIF support. Specifically, the following functions are added:
2669 +<li><a href=#gdImageOpenPolygon>gdImageOpenPolygon</a>. This is basically the same as
2670 +gdImagePolygon, but it does not join the start and end points. It is required by GD.pm.
2671 +<li><a href=#gdImageGif>gdImageGif</a>
2672 +<li><a href=#gdImageGifPtr>gdImageGifPtr</a>
2673 +<li><a href=#gdImageGifCtx>gdImageGifCtx</a>
2674 +<li><a href=#gdImageGifToSink>gdImageGifToSink</a>
2675 +<li><a href=#gdImageCreateFromGif>gdImageCreateFromGif</a>
2676 +<li><a href=#gdImageCreateFromGifCtx>gdImageCreateFromGifCtx</a>
2677 +<li><a href=#gdImageCreateFromGifPtr>gdImageCreateFromGifPtr</a>
2678 +<li>Other functions added, but not documented, are: gdImageLzw, gdImageLzwPtr,
2679 +gdImageLzwCtx, gdImageBigGif, gdImageBigGifPtr, gdImageBigGifCtx.
2682 +Note: While every effort has been made to ensure that the _WinNT_ build works, it has not
2685 <A NAME="whatsnew2.0.17"><H3>What's new in version 2.0.17?</H3></A>
2688 preprocessing them, this should not be a big problem. gd 2.0 should
2689 read old .gd and .gd2 files correctly.
2692 <P><A NAME="whatsnew1.8.4"><H3>What's new in version 1.8.4?</H3></A>
2694 <li>Add support for FreeType2 (John Ellson ellson@graphviz.org)
2697 <li>Updated links to fast-moving, always dodging libpng and zlib web sites
2700 <P><A NAME="whatsnew1.8.1"><H3>What's new in version 1.8.1?</H3></A>
2702 <li>Optional components no longer built by default (following the
2704 <a href="#gdImageCreateFromXpm"><code>gdImageCreateFromXpm</code></a>
2705 function, if the Xpm library is available. Thanks to Caolan McNamara.
2708 <P><A NAME="whatsnew1.6.3"><H3>What's new in version 1.6.3?</H3></A>
2709 Version 1.6.3 corrects a memory leak in gd_png.c. This leak caused
2710 a significant amount of memory to be allocated and not freed when
2711 @@ -1334,7 +1373,8 @@
2712 <DT><A NAME="gdPoint">gdPoint</A> <strong>(TYPE)</strong>
2714 Represents a point in the coordinate space of the image; used
2715 -by <A HREF="#gdImagePolygon">gdImagePolygon</A> and
2716 +by <A HREF="#gdImagePolygon">gdImagePolygon</A>,
2717 +<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A>, and
2718 <A HREF="#gdImageFilledPolygon">gdImageFilledPolygon</A>.
2721 @@ -1344,7 +1384,8 @@
2722 <DT><A NAME="gdPointPtr">gdPointPtr</A> <strong>(TYPE)</strong>
2724 A pointer to a <A HREF="#gdPoint">gdPoint</A> structure; passed
2725 -as an argument to <A HREF="#gdImagePolygon">gdImagePolygon</A>
2726 +as an argument to <A HREF="#gdImagePolygon">gdImagePolygon</A>,
2727 +<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A>,
2728 and <A HREF="#gdImageFilledPolygon">gdImageFilledPolygon</A>.
2730 <DT><A NAME="gdFTStringExtra">gdFTStringExtra</a> <strong>(TYPE)</strong>
2731 @@ -1457,6 +1498,77 @@
2732 /* ... Use the image ... */
2733 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2736 +<DT><A NAME="gdImageCreateFromGif">gdImageCreateFromGif(FILE *in)</A>
2737 +<strong>(FUNCTION)</strong>
2738 +<BR><A NAME="gdImageCreateFromGifCtx">gdImageCreateFromGifCtx(<a href=#gdioctx>gdIOCtx</a> *in)</A>
2739 +<strong>(FUNCTION)</strong>
2740 +<BR><A NAME="gdImageCreateFromGifPtr">gdImageCreateFromGifPtr(int size, void *data)</A>
2741 +<strong>(FUNCTION)</strong>
2744 +gdImageCreateFromGif is called to load images from GIF format files.
2745 +Invoke gdImageCreateFromGif with an already opened pointer to a file
2746 +containing the desired image.
2747 +gdImageCreateFromGif
2748 +returns a <A HREF="#gdImagePtr">gdImagePtr</A> to the new image, or NULL
2749 +if unable to load the image (most often because the file is corrupt or
2750 +does not contain a GIF image). gdImageCreateFromGif does <em>not</em>
2751 +close the file. You can inspect the sx and sy members of the
2752 +image to determine its size. The image must eventually be destroyed
2753 +using <A HREF="#gdImageDestroy">gdImageDestroy()</A>.
2755 +<A HREF="#gdImagePtr">gdImagePtr</A> im;
2756 +... inside a function ...
2758 +in = fopen("mygif.gif", "rb");
2759 +im = gdImageCreateFromGif(in);
2761 +/* ... Use the image ... */
2762 +<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2764 +<DT><A NAME="gdImageCreateFromGifSource">gdImageCreateFromGifSource(gdSourcePtr in)</A>
2765 +<strong>(FUNCTION)</strong>
2767 +gdImageCreateFromGifSource is called to load a GIF from
2768 +a data source other than a file. Usage is very similar to
2769 +the <a href="#gdImageCreateFromGif">gdImageCreateFromGif</a> function,
2770 +except that the programmer provides a custom data source.
2772 +The programmer must write an input function which accepts
2773 +a context pointer, a buffer, and a number of bytes to be
2774 +read as arguments. This function must read the number of
2775 +bytes requested, unless the end of the file has been reached,
2776 +in which case the function should return zero, or an error
2777 +has occurred, in which case the function should return
2778 +<code>-1</code>. The programmer then creates a
2779 +<a href="#gdSource">gdSource</a> structure and sets
2780 +the <code>source</code> pointer to the input function and
2781 +the context pointer to any value which is useful to the
2785 +implements <a href="#gdImageCreateFromGif">gdImageCreateFromGif</a>
2786 +by creating a custom data source and invoking gdImageCreateFromGifSource.
2788 +static int freadWrapper(void *context, char *buf, int len);
2790 +gdImagePtr gdImageCreateFromGif(FILE *in)
2793 + s.source = freadWrapper;
2795 + return gdImageCreateFromGifSource(&s);
2798 +static int freadWrapper(void *context, char *buf, int len)
2800 + int got = fread(buf, 1, len, (FILE *) context);
2806 <DT><A NAME="gdImageCreateFromPng">gdImageCreateFromPng(FILE *in)</A>
2807 <strong>(FUNCTION)</strong>
2808 <BR><A NAME="gdImageCreateFromPngCtx">gdImageCreateFromPngCtx(<a href=#gdioctx>gdIOCtx</a> *in)</A>
2809 @@ -1672,6 +1784,92 @@
2810 /* Now destroy it */
2811 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2814 +<DT><A NAME="gdImageGif">
2815 +void gdImageGif(gdImagePtr im, FILE *out)</A>
2816 +<STRONG>(FUNCTION)</STRONG>
2818 +gdImageGif outputs the specified image to the specified
2819 +file in GIF format. The file must be open for writing. Under MSDOS
2820 +and all versions of Windows, it is important to use "wb" as opposed
2821 +to simply "w" as the mode when opening the file, and under Unix there
2822 +is no penalty for doing so. gdImageGif does <em>not</em>
2823 +close the file; your code must do so.
2825 +... inside a function ...
2826 +<A HREF="#gdImagePtr">gdImagePtr</A> im;
2829 +/* Create the image */
2830 +im = <A HREF="#gdImageCreate">gdImageCreate</A>(100, 100);
2831 +/* Allocate background */
2832 +white = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 255, 255, 255);
2833 +/* Allocate drawing color */
2834 +black = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 0, 0, 0);
2835 +/* Draw rectangle */
2836 +<A HREF="#gdImageRectangle">gdImageRectangle</A>(im, 0, 0, 99, 99, black);
2837 +/* Open output file in binary mode */
2838 +out = fopen("rect.gif", "wb");
2840 +gdImageGif(im, out);
2843 +/* Destroy image */
2844 +<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2847 +<DT><A NAME="gdImageGifCtx">
2848 +void* gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)</A>
2849 +<STRONG>(FUNCTION)</STRONG>
2850 +<DD>Identical to gdImageGif except that it writes the GIF to a
2851 +<a href=#gdIOCtx>gdIOCtx</a>.
2853 +<DT><A NAME="gdImageGifPtr">
2854 +void* gdImageGifPtr(gdImagePtr im, int *size)</A>
2855 +<STRONG>(FUNCTION)</STRONG>
2856 +<DD>Identical to gdImageGif except that it returns a pointer to a memory
2857 +area with the GIF data. This memory must be freed by the caller when it is
2858 +no longer needed. The 'size' parameter received the total size of the block
2862 +<DT><A NAME="gdImageGifToSink">gdImageGifToSink(gdImagePtr im, gdSinkPtr out)</A>
2863 +<strong>(FUNCTION)</strong>
2865 +gdImageGifToSink is called to write a GIF to
2866 +a data "sink" (destination) other than a file. Usage is very similar to
2867 +the <a href="#gdImageGif">gdImageGif</a> function,
2868 +except that the programmer provides a custom data sink.
2870 +The programmer must write an output function which accepts
2871 +a context pointer, a buffer, and a number of bytes to be
2872 +written as arguments. This function must write the number of
2873 +bytes requested and return that number, unless an error
2874 +has occurred, in which case the function should return
2875 +<code>-1</code>. The programmer then creates a
2876 +<a href="#gdSink">gdSink</a> structure and sets
2877 +the <code>sink</code> pointer to the output function and
2878 +the context pointer to any value which is useful to the
2882 +implements <a href="#gdImageGif">gdImageGif</a>
2883 +by creating a custom data source and invoking gdImageGifFromSink.
2885 +static int stdioSink(void *context, char *buffer, int len)
2887 + return fwrite(buffer, 1, len, (FILE *) context);
2890 +void gdImageGif(gdImagePtr im, FILE *out)
2893 + mySink.context = (void *) out;
2894 + mySink.sink = stdioSink;
2895 + gdImageGifToSink(im, &mySink);
2899 <DT><A NAME="gdImageJpeg">
2900 void gdImageJpeg(gdImagePtr im, FILE *out, int quality)</A>
2901 <STRONG>(FUNCTION)</STRONG><BR>
2902 @@ -2133,6 +2331,15 @@
2904 <A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
2907 +<DT><A NAME="gdImageOpenPolygon">void gdImageOpenPolygon(gdImagePtr im, gdPointPtr points, int pointsTotal, int color)</A>
2908 +<STRONG>(FUNCTION)</STRONG>
2910 +gdImageOpenPolygon is used to draw an open polygon (ie. series of line segments). It is almost identical
2911 +to <A HREF="#gdImagePolygon">gdImagePolygon</A>, except that it does not join the last point to the
2915 <DT><A NAME="gdImageRectangle">void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)</A>
2916 <STRONG>(FUNCTION)</STRONG>
2918 @@ -4488,6 +4695,10 @@
2919 <A HREF="#gdImageCreateFromGd2Part">gdImageCreateFromGd2Part</A> |
2920 <A HREF="#gdImageCreateFromGd2PartCtx">gdImageCreateFromGd2PartCtx</A> |
2921 <A HREF="#gdImageCreateFromGd2PartPtr">gdImageCreateFromGd2PartPtr</A> |
2922 +<A HREF="#gdImageCreateFromGif">gdImageCreateFromGif</A> |
2923 +<A HREF="#gdImageCreateFromGifCtx">gdImageCreateFromGifCtx</A> |
2924 +<A HREF="#gdImageCreateFromGifPtr">gdImageCreateFromGifPtr</A> |
2925 +<A HREF="#gdImageCreateFromGifSource">gdImageCreateFromGifSource</A> |
2926 <A HREF="#gdImageCreateFromJpeg">gdImageCreateFromJpeg</A> |
2927 <A HREF="#gdImageCreateFromJpegCtx">gdImageCreateFromJpegCtx</A> |
2928 <A HREF="#gdImageCreateFromJpegPtr">gdImageCreateFromJpegPtr</A> |
2929 @@ -4507,6 +4718,10 @@
2930 <A HREF="#gdImageGetInterlaced">gdImageGetInterlaced</A> |
2931 <A HREF="#gdImageGetPixel">gdImageGetPixel</A> |
2932 <A HREF="#gdImageGetTransparent">gdImageGetTransparent</A> |
2933 +<A HREF="#gdImageGif">gdImageGif</A> |
2934 +<A HREF="#gdImageGifCtx">gdImageGifCtx</A> |
2935 +<A HREF="#gdImageGifPtr">gdImageGifPtr</A> |
2936 +<A HREF="#gdImageGifToSink">gdImageGifToSink</A> |
2937 <A HREF="#gdImageGreen">gdImageGreen</A> |
2938 <A HREF="#gdImageInterlace">gdImageInterlace</A> |
2939 <A HREF="#gdImageJpeg">gdImageJpeg</A> |
2940 @@ -4522,6 +4737,7 @@
2941 <A HREF="#gdImagePngPtrEx">gdImagePngPtrEx</A> |
2942 <A HREF="#gdImagePngToSink">gdImagePngToSink</A> |
2943 <A HREF="#gdImagePolygon">gdImagePolygon</A> |
2944 +<A HREF="#gdImageOpenPolygon">gdImageOpenPolygon</A> |
2945 <A HREF="#gdImagePtr">gdImagePtr</A> |
2946 <A HREF="#gdImageWBMP">gdImageWBMP</A> |
2947 <A HREF="#gdImageWBMPCtx">gdImageWBMPCtx</A> |
2948 diff -Nur gd-2.0.17.orig/Makefile.am gd-2.0.17/Makefile.am
2949 --- gd-2.0.17.orig/Makefile.am 2003-12-25 02:50:00.000000000 +0100
2950 +++ gd-2.0.17/Makefile.am 2003-12-26 15:36:42.047006544 +0100
2953 SUBDIRS = config test
2955 -bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng
2956 +bin_PROGRAMS = annotate gdparttopng gdtopng gd2copypal gd2topng pngtogd pngtogd2 webpng gd2togif gdcmpgif giftogd2
2958 bin_SCRIPTS = bdftogd
2962 lib_LTLIBRARIES = libgd.la
2964 -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
2965 +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
2967 libgd_la_LDFLAGS = -version-info 2:0:0
2969 Pliki gd-2.0.17.orig/test/fttestref.png i gd-2.0.17/test/fttestref.png ró¿ni± siê