diff options
Diffstat (limited to 'lang/php4/files/patch-ext::gd::libgd::gd_biggif_out.c')
-rw-r--r-- | lang/php4/files/patch-ext::gd::libgd::gd_biggif_out.c | 1087 |
1 files changed, 0 insertions, 1087 deletions
diff --git a/lang/php4/files/patch-ext::gd::libgd::gd_biggif_out.c b/lang/php4/files/patch-ext::gd::libgd::gd_biggif_out.c deleted file mode 100644 index e18fc2f9b4e1..000000000000 --- a/lang/php4/files/patch-ext::gd::libgd::gd_biggif_out.c +++ /dev/null @@ -1,1087 +0,0 @@ ---- ext/gd/libgd/gd_biggif_out.c.orig Sat Jun 28 15:47:56 2003 -+++ ext/gd/libgd/gd_biggif_out.c Sat Jun 28 15:47:56 2003 -@@ -0,0 +1,1084 @@ -+#include <stdio.h> -+#include <math.h> -+#include <string.h> -+#include <stdlib.h> -+#include "gd.h" -+#include "gdhelpers.h" -+ -+/* -+** Wrapper functions for this module. -+*/ -+ -+void gdImageBigGif(gdImagePtr im, FILE *outFile) -+{ -+ gdIOCtx *out = gdNewFileCtx(outFile); -+ gdImageBigGifCtx(im, out); -+ out->gd_free(out); -+} -+ -+void* gdImageBigGifPtr(gdImagePtr im, int *size) -+{ -+ void *rv; -+ gdIOCtx *out = gdNewDynamicCtx(2048, NULL); -+ gdImageBigGifCtx(im, out); -+ rv = gdDPExtractData(out,size); -+ out->gd_free(out); -+ return rv; -+} -+ -+void gdImageGifAnimBegin(gdImagePtr im, FILE *outFile, int GlobalCM, int Loops) -+{ -+ gdIOCtx *out = gdNewFileCtx(outFile); -+ gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops); -+ out->gd_free(out); -+} -+ -+void *gdImageGifAnimBeginPtr(gdImagePtr im, int *size, int GlobalCM, int Loops) -+{ -+ void *rv; -+ gdIOCtx *out = gdNewDynamicCtx(2048, NULL); -+ gdImageGifAnimBeginCtx(im, out, GlobalCM, Loops); -+ rv = gdDPExtractData(out,size); -+ out->gd_free(out); -+ return rv; -+} -+ -+void gdImageBigGifAnimAdd(gdImagePtr im, FILE *outFile, int LocalCM, int LeftOfs, int TopOfs, int Delay, int Disposal) -+{ -+ gdIOCtx *out = gdNewFileCtx(outFile); -+ gdImageBigGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal); -+ out->gd_free(out); -+} -+ -+void *gdImageBigGifAnimAddPtr(gdImagePtr im, int *size, int LocalCM, int LeftOfs, int TopOfs, int Delay, int Disposal) -+{ -+ void *rv; -+ gdIOCtx *out = gdNewDynamicCtx(2048, NULL); -+ gdImageBigGifAnimAddCtx(im, out, LocalCM, LeftOfs, TopOfs, Delay, Disposal); -+ rv = gdDPExtractData(out,size); -+ out->gd_free(out); -+ return rv; -+} -+ -+void gdImageGifAnimEnd(FILE *outFile) -+{ -+#if 1 -+ putc (';', outFile); -+#else -+ gdIOCtx *out = gdNewFileCtx(outFile); -+ gdImageGifAnimEndCtx(out); -+ out->gd_free(out); -+#endif -+} -+ -+void* gdImageGifAnimEndPtr(int *size) -+{ -+ char *rv = (char *) gdMalloc (1); -+ *rv = ';'; -+ *size = 1; -+ return (void *)rv; -+} -+ -+ -+/* Code drawn from ppmtogif.c, from the pbmplus package -+** -+** Based on GIFENCOD by David Rowley <mgardi@watdscu.waterloo.edu>. A -+** Lempel-Zim compression based on "compress". -+** -+** Modified by Marcel Wijkstra <wijkstra@fwi.uva.nl> -+** -+** Copyright (C) 1989 by Jef Poskanzer. -+** -+** Permission to use, copy, modify, and distribute this software and its -+** documentation for any purpose and without fee is hereby granted, provided -+** that the above copyright notice appear in all copies and that both that -+** copyright notice and this permission notice appear in supporting -+** documentation. This software is provided "as is" without express or -+** implied warranty. -+** -+** The Graphics Interchange Format(c) is the Copyright property of -+** CompuServe Incorporated. GIF(sm) is a Service Mark property of -+** CompuServe Incorporated. -+* -+* Heavily modified by Mouse, 1998-02-12. -+* Remove LZW compression. -+* Added miGIF run length compression. -+* -+*/ -+ -+/* -+ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1 -+ */ -+typedef int code_int; -+ -+static int colorstobpp(int colors); -+static void BumpPixel (void); -+static int GIFNextPixel (gdImagePtr im); -+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); -+static void GIFAnimEncode(gdIOCtx *fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, int GInterlace, int Transparent, int Delay, int Disposal, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im); -+/*static void Putword (int w, gdIOCtx *fp); */ -+static void GIFcompress (int, gdIOCtx *, gdImagePtr); -+static void output (code_int code); -+ -+/* UNUSED -+* static void char_init (void); -+* static void char_out (int c); -+*/ -+ -+/* Allows for reuse */ -+static void init_statics(void); -+ -+void gdImageBigGifCtx(gdImagePtr im, gdIOCtx *out) -+{ -+ int interlace, transparent, BitsPerPixel; -+ -+ interlace = im->interlace; -+ transparent = im->transparent; -+ -+ BitsPerPixel = colorstobpp(im->colorsTotal); -+ /* Clear any old values in statics strewn through the GIF code */ -+ init_statics(); -+ /* All set, let's do it. */ -+ GIFEncode( -+ out, im->sx, im->sy, interlace, 0, transparent, BitsPerPixel, -+ im->red, im->green, im->blue, im); -+} -+ -+void gdImageGifAnimBeginCtx(gdImagePtr im, gdIOCtx *out, int GlobalCM, int Loops) -+{ -+ int B; -+ int RWidth, RHeight; -+ int Resolution; -+ int ColorMapSize; -+ int BitsPerPixel; -+ int Background = 0; -+ int i; -+ -+ BitsPerPixel = colorstobpp(im->colorsTotal); -+ ColorMapSize = 1 << BitsPerPixel; -+ -+ RWidth = im->sx; -+ RHeight = im->sy; -+ -+ Resolution = BitsPerPixel; -+ -+ /* -+ * Write the Magic header -+ */ -+ gdPutBuf( "GIF89a", 6, out ); -+ -+ /* -+ * Write out the screen width and height -+ */ -+ Putword( RWidth, out ); -+ Putword( RHeight, out ); -+ -+ /* -+ * Indicate that there is a global colour map -+ */ -+ B = GlobalCM > 0 ? 0x80 : 0; -+ -+ /* -+ * OR in the resolution -+ */ -+ B |= (Resolution - 1) << 5; -+ -+ /* -+ * OR in the Bits per Pixel -+ */ -+ B |= (BitsPerPixel - 1); -+ -+ /* -+ * Write it out -+ */ -+ gdPutC( B, out ); -+ -+ /* -+ * Write out the Background colour -+ */ -+ gdPutC( Background, out ); -+ -+ /* -+ * Byte of 0's (future expansion) -+ */ -+ gdPutC( 0, out ); -+ -+ /* -+ * Write out the Global Colour Map -+ */ -+ if (GlobalCM > 0) -+ for( i=0; i<ColorMapSize; ++i ) { -+ gdPutC( im->red[i], out ); -+ gdPutC( im->green[i], out ); -+ gdPutC( im->blue[i], out ); -+ } -+ if (Loops >= 0) { -+ gdPutBuf( "!\377\13NETSCAPE2.0\3\1", 16, out ); -+ gdPutC( (unsigned char)(Loops & 255), out ); -+ gdPutC( (unsigned char)((Loops >> 8) & 255), out ); -+ gdPutC( 0, out ); -+ } -+} -+ -+void gdImageBigGifAnimAddCtx(gdImagePtr im, gdIOCtx *out, int LocalCM, int LeftOfs, int TopOfs, int Delay, int Disposal) -+{ -+ int interlace, transparent, BitsPerPixel; -+ -+ interlace = im->interlace; -+ transparent = im->transparent; -+ -+ BitsPerPixel = colorstobpp(im->colorsTotal); -+ /* Clear any old values in statics strewn through the GIF code */ -+ init_statics(); -+ /* All set, let's do it. */ -+ GIFAnimEncode( -+ out, im->sx, im->sy, LeftOfs, TopOfs, interlace, transparent, -+ Delay, Disposal, BitsPerPixel, -+ LocalCM > 0 ? im->red : 0, im->green, im->blue, im); -+} -+ -+void gdImageGifAnimEndCtx(gdIOCtx *out) -+{ -+ /* -+ * Write the GIF file terminator -+ */ -+ gdPutC( ';', out ); -+} -+ -+ -+static int -+colorstobpp(int colors) -+{ -+ int bpp = 0; -+ -+ if ( colors <= 2 ) -+ bpp = 1; -+ else if ( colors <= 4 ) -+ bpp = 2; -+ else if ( colors <= 8 ) -+ bpp = 3; -+ else if ( colors <= 16 ) -+ bpp = 4; -+ else if ( colors <= 32 ) -+ bpp = 5; -+ else if ( colors <= 64 ) -+ bpp = 6; -+ else if ( colors <= 128 ) -+ bpp = 7; -+ else if ( colors <= 256 ) -+ bpp = 8; -+ return bpp; -+ } -+ -+/***************************************************************************** -+ * -+ * GIFENCODE.C - GIF Image compression interface -+ * -+ * GIFEncode( FName, GHeight, GWidth, GInterlace, Background, Transparent, -+ * BitsPerPixel, Red, Green, Blue, gdImagePtr ) -+ * -+ *****************************************************************************/ -+ -+#define TRUE 1 -+#define FALSE 0 -+ -+static int Width, Height; -+static int curx, cury; -+static long CountDown; -+static int Pass = 0; -+static int Interlace; -+ -+/* -+ * Bump the 'curx' and 'cury' to point to the next pixel -+ */ -+static void -+BumpPixel(void) -+{ -+ /* -+ * Bump the current X position -+ */ -+ ++curx; -+ -+ /* -+ * If we are at the end of a scan line, set curx back to the beginning -+ * If we are interlaced, bump the cury to the appropriate spot, -+ * otherwise, just increment it. -+ */ -+ if( curx == Width ) { -+ curx = 0; -+ -+ if( !Interlace ) -+ ++cury; -+ else { -+ switch( Pass ) { -+ -+ case 0: -+ cury += 8; -+ if( cury >= Height ) { -+ ++Pass; -+ cury = 4; -+ } -+ break; -+ -+ case 1: -+ cury += 8; -+ if( cury >= Height ) { -+ ++Pass; -+ cury = 2; -+ } -+ break; -+ -+ case 2: -+ cury += 4; -+ if( cury >= Height ) { -+ ++Pass; -+ cury = 1; -+ } -+ break; -+ -+ case 3: -+ cury += 2; -+ break; -+ } -+ } -+ } -+} -+ -+/* -+ * Return the next pixel from the image -+ */ -+static int -+GIFNextPixel(gdImagePtr im) -+{ -+ int r; -+ -+ if( CountDown == 0 ) -+ return EOF; -+ -+ --CountDown; -+ -+ r = gdImageGetPixel(im, curx, cury); -+ -+ BumpPixel(); -+ -+ return r; -+} -+ -+/* public */ -+ -+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) -+{ -+ int B; -+ int RWidth, RHeight; -+ int LeftOfs, TopOfs; -+ int Resolution; -+ int ColorMapSize; -+ int InitCodeSize; -+ int i; -+ -+ Interlace = GInterlace; -+ -+ ColorMapSize = 1 << BitsPerPixel; -+ -+ RWidth = Width = GWidth; -+ RHeight = Height = GHeight; -+ LeftOfs = TopOfs = 0; -+ -+ Resolution = BitsPerPixel; -+ -+ /* -+ * Calculate number of bits we are expecting -+ */ -+ CountDown = (long)Width * (long)Height; -+ -+ /* -+ * Indicate which pass we are on (if interlace) -+ */ -+ Pass = 0; -+ -+ /* -+ * The initial code size -+ */ -+ if( BitsPerPixel <= 1 ) -+ InitCodeSize = 2; -+ else -+ InitCodeSize = BitsPerPixel; -+ -+ /* -+ * Set up the current x and y position -+ */ -+ curx = cury = 0; -+ -+ /* -+ * Write the Magic header -+ */ -+ gdPutBuf( Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp ); -+ -+ /* -+ * Write out the screen width and height -+ */ -+ Putword( RWidth, fp ); -+ Putword( RHeight, fp ); -+ -+ /* -+ * Indicate that there is a global colour map -+ */ -+ B = 0x80; /* Yes, there is a color map */ -+ -+ /* -+ * OR in the resolution -+ */ -+ B |= (Resolution - 1) << 5; -+ -+ /* -+ * OR in the Bits per Pixel -+ */ -+ B |= (BitsPerPixel - 1); -+ -+ /* -+ * Write it out -+ */ -+ gdPutC( B, fp ); -+ -+ /* -+ * Write out the Background colour -+ */ -+ gdPutC( Background, fp ); -+ -+ /* -+ * Byte of 0's (future expansion) -+ */ -+ gdPutC( 0, fp ); -+ -+ /* -+ * Write out the Global Colour Map -+ */ -+ for( i=0; i<ColorMapSize; ++i ) { -+ gdPutC( Red[i], fp ); -+ gdPutC( Green[i], fp ); -+ gdPutC( Blue[i], fp ); -+ } -+ -+ /* -+ * Write out extension for transparent colour index, if necessary. -+ */ -+ if ( Transparent >= 0 ) { -+ gdPutC( '!', fp ); -+ gdPutC( 0xf9, fp ); -+ gdPutC( 4, fp ); -+ gdPutC( 1, fp ); -+ gdPutC( 0, fp ); -+ gdPutC( 0, fp ); -+ gdPutC( (unsigned char) Transparent, fp ); -+ gdPutC( 0, fp ); -+ } -+ -+ /* -+ * Write an Image separator -+ */ -+ gdPutC( ',', fp ); -+ -+ /* -+ * Write the Image header -+ */ -+ -+ Putword( LeftOfs, fp ); -+ Putword( TopOfs, fp ); -+ Putword( Width, fp ); -+ Putword( Height, fp ); -+ -+ /* -+ * Write out whether or not the image is interlaced -+ */ -+ if( Interlace ) -+ gdPutC( 0x40, fp ); -+ else -+ gdPutC( 0x00, fp ); -+ -+ /* -+ * Write out the initial code size -+ */ -+ gdPutC( InitCodeSize, fp ); -+ -+ /* -+ * Go and actually compress the data -+ */ -+ GIFcompress( InitCodeSize+1, fp, im ); -+ -+ /* -+ * Write out a Zero-length packet (to end the series) -+ */ -+ gdPutC( 0, fp ); -+ -+ /* -+ * Write the GIF file terminator -+ */ -+ gdPutC( ';', fp ); -+} -+ -+static void -+GIFAnimEncode(gdIOCtx *fp, int IWidth, int IHeight, int LeftOfs, int TopOfs, int GInterlace, int Transparent, int Delay, int Disposal, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im) -+{ -+ int ColorMapSize; -+ int InitCodeSize; -+ int i; -+ -+ if (LeftOfs < 0) LeftOfs = 0; -+ if (TopOfs < 0) TopOfs = 0; -+ if (Delay < 0) Delay = 100; -+ if (Disposal < 0) Disposal = 2; -+ -+ Interlace = GInterlace; -+ -+ ColorMapSize = 1 << BitsPerPixel; -+ -+ Width = IWidth; -+ Height = IHeight; -+ -+ /* -+ * Calculate number of bits we are expecting -+ */ -+ CountDown = (long)Width * (long)Height; -+ -+ /* -+ * Indicate which pass we are on (if interlace) -+ */ -+ Pass = 0; -+ -+ /* -+ * The initial code size -+ */ -+ if( BitsPerPixel <= 1 ) -+ InitCodeSize = 2; -+ else -+ InitCodeSize = BitsPerPixel; -+ -+ /* -+ * Set up the current x and y position -+ */ -+ curx = cury = 0; -+ -+ /* -+ * Write out extension for image animation and looping -+ */ -+ gdPutC( '!', fp ); -+ gdPutC( 0xf9, fp ); -+ gdPutC( 4, fp ); -+ gdPutC( (Transparent >= 0 ? 1 : 0) -+ | (Disposal << 2), fp ); -+ gdPutC( (unsigned char)(Delay & 255), fp ); -+ gdPutC( (unsigned char)((Delay >> 8) & 255), fp ); -+ gdPutC( (unsigned char) Transparent, fp ); -+ gdPutC( 0, fp ); -+ -+ /* -+ * Write an Image separator -+ */ -+ gdPutC( ',', fp ); -+ -+ /* -+ * Write the Image header -+ */ -+ -+ Putword( LeftOfs, fp ); -+ Putword( TopOfs, fp ); -+ Putword( Width, fp ); -+ Putword( Height, fp ); -+ -+ /* -+ * Write out whether or not the image is interlaced -+ * and if it includes local colour map. -+ */ -+ gdPutC( (Interlace ? 0x40 : 0) -+ | (Red ? 0x80 : 0) -+ | (Red ? BitsPerPixel - 1 : 0), fp ); -+ -+ /* -+ * Write out the Local Colour Map -+ */ -+ if (Red) -+ for( i=0; i<ColorMapSize; ++i ) { -+ gdPutC( Red[i], fp ); -+ gdPutC( Green[i], fp ); -+ gdPutC( Blue[i], fp ); -+ } -+ -+ /* -+ * Write out the initial code size -+ */ -+ gdPutC( InitCodeSize, fp ); -+ -+ /* -+ * Go and actually compress the data -+ */ -+ GIFcompress( InitCodeSize+1, fp, im ); -+ -+ /* -+ * Write out a Zero-length packet (to end the series) -+ */ -+ gdPutC( 0, fp ); -+} -+ -+/* Write out a word to the GIF file */ -+/*static void */ -+/*Putword(int w, gdIOCtx *fp) */ -+/*{ */ -+/* fputc( w & 0xff, fp ); */ -+/* fputc( (w / 256) & 0xff, fp ); */ -+/*} */ -+ -+#define GIFBITS 12 -+ -+/*----------------------------------------------------------------------- -+ * -+ * miGIF Compression - mouse and ivo's GIF-compatible compression -+ * -+ * -run length encoding compression routines- -+ * -+ * Copyright (C) 1998 Hutchison Avenue Software Corporation -+ * http://www.hasc.com -+ * info@hasc.com -+ * -+ * Permission to use, copy, modify, and distribute this software and its -+ * documentation for any purpose and without fee is hereby granted, provided -+ * that the above copyright notice appear in all copies and that both that -+ * copyright notice and this permission notice appear in supporting -+ * documentation. This software is provided "AS IS." The Hutchison Avenue -+ * Software Corporation disclaims all warranties, either express or implied, -+ * including but not limited to implied warranties of merchantability and -+ * fitness for a particular purpose, with respect to this code and accompanying -+ * documentation. -+ * -+ * The miGIF compression routines do not, strictly speaking, generate files -+ * conforming to the GIF spec, since the image data is not LZW-compressed -+ * (this is the point: in order to avoid transgression of the Unisys patent -+ * on the LZW algorithm.) However, miGIF generates data streams that any -+ * reasonably sane LZW decompresser will decompress to what we want. -+ * -+ * miGIF compression uses run length encoding. It compresses horizontal runs -+ * of pixels of the same color. This type of compression gives good results -+ * on images with many runs, for example images with lines, text and solid -+ * shapes on a solid-colored background. It gives little or no compression -+ * on images with few runs, for example digital or scanned photos. -+ * -+ * der Mouse -+ * mouse@rodents.montreal.qc.ca -+ * 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B -+ * -+ * ivo@hasc.com -+ * -+ * The Graphics Interchange Format(c) is the Copyright property of -+ * CompuServe Incorporated. GIF(sm) is a Service Mark property of -+ * CompuServe Incorporated. -+ * -+ */ -+ -+static int rl_pixel; -+static int rl_basecode; -+static int rl_count; -+static int rl_table_pixel; -+static int rl_table_max; -+static int just_cleared; -+static int out_bits; -+static int out_bits_init; -+static int out_count; -+static int out_bump; -+static int out_bump_init; -+static int out_clear; -+static int out_clear_init; -+static int max_ocodes; -+static int code_clear; -+static int code_eof; -+static unsigned int obuf; -+static int obits; -+static gdIOCtx *ofile; -+static unsigned char oblock[256]; -+static int oblen; -+ -+/* Used only when debugging GIF compression code */ -+/* #define DEBUGGING_ENVARS */ -+ -+#ifdef DEBUGGING_ENVARS -+ -+static int verbose_set = 0; -+static int verbose; -+#define VERBOSE (verbose_set?verbose:set_verbose()) -+ -+static int set_verbose(void) -+{ -+ verbose = !!getenv("GIF_VERBOSE"); -+ verbose_set = 1; -+ return(verbose); -+} -+ -+#else -+ -+#define VERBOSE 0 -+ -+#endif -+ -+ -+static const char *binformat(unsigned int v, int nbits) -+{ -+ static char bufs[8][64]; -+ static int bhand = 0; -+ unsigned int bit; -+ int bno; -+ char *bp; -+ -+ bhand --; -+ if (bhand < 0) bhand = (sizeof(bufs)/sizeof(bufs[0]))-1; -+ bp = &bufs[bhand][0]; -+ for (bno=nbits-1,bit=1U<<bno;bno>=0;bno--,bit>>=1) -+ { *bp++ = (v & bit) ? '1' : '0'; -+ if (((bno&3) == 0) && (bno != 0)) *bp++ = '.'; -+ } -+ *bp = '\0'; -+ return(&bufs[bhand][0]); -+} -+ -+static void write_block(void) -+{ -+ int i; -+ -+ if (VERBOSE) -+ { printf("write_block %d:",oblen); -+ for (i=0;i<oblen;i++) printf(" %02x",oblock[i]); -+ printf("\n"); -+ } -+ gdPutC(oblen,ofile); -+ gdPutBuf(&oblock[0],oblen,ofile); -+ oblen = 0; -+} -+ -+static void block_out(unsigned char c) -+{ -+ if (VERBOSE) printf("block_out %s\n",binformat(c,8)); -+ oblock[oblen++] = c; -+ if (oblen >= 255) write_block(); -+} -+ -+static void block_flush(void) -+{ -+ if (VERBOSE) printf("block_flush\n"); -+ if (oblen > 0) write_block(); -+} -+ -+static void output(int val) -+{ -+ if (VERBOSE) printf("output %s [%s %d %d]\n",binformat(val,out_bits),binformat(obuf,obits),obits,out_bits); -+ obuf |= val << obits; -+ obits += out_bits; -+ while (obits >= 8) -+ { block_out(obuf&0xff); -+ obuf >>= 8; -+ obits -= 8; -+ } -+ if (VERBOSE) printf("output leaving [%s %d]\n",binformat(obuf,obits),obits); -+} -+ -+static void output_flush(void) -+{ -+ if (VERBOSE) printf("output_flush\n"); -+ if (obits > 0) block_out(obuf); -+ block_flush(); -+} -+ -+static void did_clear(void) -+{ -+ if (VERBOSE) printf("did_clear\n"); -+ out_bits = out_bits_init; -+ out_bump = out_bump_init; -+ out_clear = out_clear_init; -+ out_count = 0; -+ rl_table_max = 0; -+ just_cleared = 1; -+} -+ -+static void output_plain(int c) -+{ -+ if (VERBOSE) printf("output_plain %s\n",binformat(c,out_bits)); -+ just_cleared = 0; -+ output(c); -+ out_count ++; -+ if (out_count >= out_bump) -+ { out_bits ++; -+ out_bump += 1 << (out_bits - 1); -+ } -+ if (out_count >= out_clear) -+ { output(code_clear); -+ did_clear(); -+ } -+} -+ -+static unsigned int isqrt(unsigned int x) -+{ -+ unsigned int r; -+ unsigned int v; -+ -+ if (x < 2) return(x); -+ for (v=x,r=1;v;v>>=2,r<<=1) ; -+ while (1) -+ { v = ((x / r) + r) / 2; -+ if ((v == r) || (v == r+1)) return(r); -+ r = v; -+ } -+} -+ -+static unsigned int compute_triangle_count(unsigned int count, unsigned int nrepcodes) -+{ -+ unsigned int perrep; -+ unsigned int cost; -+ -+ cost = 0; -+ perrep = (nrepcodes * (nrepcodes+1)) / 2; -+ while (count >= perrep) -+ { cost += nrepcodes; -+ count -= perrep; -+ } -+ if (count > 0) -+ { unsigned int n; -+ n = isqrt(count); -+ while ((n*(n+1)) >= 2*count) n --; -+ while ((n*(n+1)) < 2*count) n ++; -+ cost += n; -+ } -+ return(cost); -+} -+ -+static void max_out_clear(void) -+{ -+ out_clear = max_ocodes; -+} -+ -+static void reset_out_clear(void) -+{ -+ out_clear = out_clear_init; -+ if (out_count >= out_clear) -+ { output(code_clear); -+ did_clear(); -+ } -+} -+ -+static void rl_flush_fromclear(int count) -+{ -+ int n; -+ -+ if (VERBOSE) printf("rl_flush_fromclear %d\n",count); -+ max_out_clear(); -+ rl_table_pixel = rl_pixel; -+ n = 1; -+ while (count > 0) -+ { if (n == 1) -+ { rl_table_max = 1; -+ output_plain(rl_pixel); -+ count --; -+ } -+ else if (count >= n) -+ { rl_table_max = n; -+ output_plain(rl_basecode+n-2); -+ count -= n; -+ } -+ else if (count == 1) -+ { rl_table_max ++; -+ output_plain(rl_pixel); -+ count = 0; -+ } -+ else -+ { rl_table_max ++; -+ output_plain(rl_basecode+count-2); -+ count = 0; -+ } -+ if (out_count == 0) n = 1; else n ++; -+ } -+ reset_out_clear(); -+ if (VERBOSE) printf("rl_flush_fromclear leaving table_max=%d\n",rl_table_max); -+} -+ -+static void rl_flush_clearorrep(int count) -+{ -+ int withclr; -+ -+ if (VERBOSE) printf("rl_flush_clearorrep %d\n",count); -+ withclr = 1 + compute_triangle_count(count,max_ocodes); -+ if (withclr < count) -+ { output(code_clear); -+ did_clear(); -+ rl_flush_fromclear(count); -+ } -+ else -+ { for (;count>0;count--) output_plain(rl_pixel); -+ } -+} -+ -+static void rl_flush_withtable(int count) -+{ -+ int repmax; -+ int repleft; -+ int leftover; -+ -+ if (VERBOSE) printf("rl_flush_withtable %d\n",count); -+ repmax = count / rl_table_max; -+ leftover = count % rl_table_max; -+ repleft = (leftover ? 1 : 0); -+ if (out_count+repmax+repleft > max_ocodes) -+ { repmax = max_ocodes - out_count; -+ leftover = count - (repmax * rl_table_max); -+ repleft = 1 + compute_triangle_count(leftover,max_ocodes); -+ } -+ if (VERBOSE) printf("rl_flush_withtable repmax=%d leftover=%d repleft=%d\n",repmax,leftover,repleft); -+ if (1+compute_triangle_count(count,max_ocodes) < repmax+repleft) -+ { output(code_clear); -+ did_clear(); -+ rl_flush_fromclear(count); -+ return; -+ } -+ max_out_clear(); -+ for (;repmax>0;repmax--) output_plain(rl_basecode+rl_table_max-2); -+ if (leftover) -+ { if (just_cleared) -+ { rl_flush_fromclear(leftover); -+ } -+ else if (leftover == 1) -+ { output_plain(rl_pixel); -+ } -+ else -+ { output_plain(rl_basecode+leftover-2); -+ } -+ } -+ reset_out_clear(); -+} -+ -+static void rl_flush(void) -+{ -+ /* UNUSED int table_reps; */ -+ /* UNUSED int table_extra; */ -+ -+ if (VERBOSE) printf("rl_flush [ %d %d\n",rl_count,rl_pixel); -+ if (rl_count == 1) -+ { output_plain(rl_pixel); -+ rl_count = 0; -+ if (VERBOSE) printf("rl_flush ]\n"); -+ return; -+ } -+ if (just_cleared) -+ { rl_flush_fromclear(rl_count); -+ } -+ else if ((rl_table_max < 2) || (rl_table_pixel != rl_pixel)) -+ { rl_flush_clearorrep(rl_count); -+ } -+ else -+ { rl_flush_withtable(rl_count); -+ } -+ if (VERBOSE) printf("rl_flush ]\n"); -+ rl_count = 0; -+} -+ -+static void GIFcompress(int init_bits, gdIOCtx *outfile, gdImagePtr im) -+{ -+ int c; -+ -+ ofile = outfile; -+ obuf = 0; -+ obits = 0; -+ oblen = 0; -+ code_clear = 1 << (init_bits - 1); -+ code_eof = code_clear + 1; -+ rl_basecode = code_eof + 1; -+ out_bump_init = (1 << (init_bits - 1)) - 1; -+ /* for images with a lot of runs, making out_clear_init larger will -+ give better compression. */ -+ out_clear_init = (init_bits <= 3) ? 9 : (out_bump_init-1); -+#ifdef DEBUGGING_ENVARS -+ { const char *ocienv; -+ ocienv = getenv("GIF_OUT_CLEAR_INIT"); -+ if (ocienv) -+ { out_clear_init = atoi(ocienv); -+ if (VERBOSE) printf("[overriding out_clear_init to %d]\n",out_clear_init); -+ } -+ } -+#endif -+ out_bits_init = init_bits; -+ max_ocodes = (1 << GIFBITS) - ((1 << (out_bits_init - 1)) + 3); -+ did_clear(); -+ output(code_clear); -+ rl_count = 0; -+ while (1) -+ { c = GIFNextPixel(im); -+ if ((rl_count > 0) && (c != rl_pixel)) rl_flush(); -+ if (c == EOF) break; -+ if (rl_pixel == c) -+ { rl_count ++; -+ } -+ else -+ { rl_pixel = c; -+ rl_count = 1; -+ } -+ } -+ output(code_eof); -+ output_flush(); -+} -+ -+/*----------------------------------------------------------------------- -+ * -+ * End of miGIF section - See copyright notice at start of section. -+ * -+ *----------------------------------------------------------------------- -+*/ -+ -+/****************************************************************************** -+ * -+ * GIF Specific routines -+ * -+ ******************************************************************************/ -+ -+/* -+ * Number of characters so far in this 'packet' -+ */ -+static int a_count; -+ -+/* -+ * Set up the 'byte output' routine -+ */ -+ -+/* UNUSED -+* static void -+* char_init(void) -+* { -+* a_count = 0; -+* } -+*/ -+ -+/* -+ * Define the storage for the packet accumulator -+ */ -+ -+/* UNUSED static char accum[ 256 ]; */ -+ -+static void init_statics(void) { -+ /* Some of these are properly initialized later. What I'm doing -+ here is making sure code that depends on C's initialization -+ of statics doesn't break when the code gets called more -+ than once. */ -+ Width = 0; -+ Height = 0; -+ curx = 0; -+ cury = 0; -+ CountDown = 0; -+ Pass = 0; -+ Interlace = 0; -+ a_count = 0; -+} -+ -+ -+/* +-------------------------------------------------------------------+ */ -+/* | Copyright 1990, 1991, 1993, David Koblas. (koblas@netcom.com) | */ -+/* | Permission to use, copy, modify, and distribute this software | */ -+/* | and its documentation for any purpose and without fee is hereby | */ -+/* | granted, provided that the above copyright notice appear in all | */ -+/* | copies and that both that copyright notice and this permission | */ -+/* | notice appear in supporting documentation. This software is | */ -+/* | provided "as is" without express or implied warranty. | */ -+/* +-------------------------------------------------------------------+ */ -+ |