this is not needed anymore
[rrdtool.git] / libraries / gd1.3 / gd.c
diff --git a/libraries/gd1.3/gd.c b/libraries/gd1.3/gd.c
deleted file mode 100644 (file)
index 9ab33d5..0000000
+++ /dev/null
@@ -1,2147 +0,0 @@
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#include <stdlib.h>
-#include "gd.h"
-#include "mtables.c"
-
-static void gdImageBrushApply(gdImagePtr im, int x, int y);
-static void gdImageTileApply(gdImagePtr im, int x, int y);
-
-gdImagePtr gdImageCreate(int sx, int sy)
-{
-       int i;
-       gdImagePtr im;
-       im = (gdImage *) calloc(1,sizeof(gdImage));
-       /* NOW ROW-MAJOR IN GD 1.3 */
-       im->pixels = (unsigned char **) malloc(sizeof(unsigned char *) * sy);
-       im->polyInts = 0;
-       im->polyAllocated = 0;
-       im->brush = 0;
-       im->tile = 0;
-       im->style = 0;
-       for (i=0; (i<sy); i++) {
-               /* NOW ROW-MAJOR IN GD 1.3 */
-               im->pixels[i] = (unsigned char *) calloc(
-                       sx, sizeof(unsigned char));
-       }       
-       im->sx = sx;
-       im->sy = sy;
-       im->colorsTotal = 0;
-       im->transparent = (-1);
-       im->interlace = 0;
-       return im;
-}
-
-void gdImageDestroy(gdImagePtr im)
-{
-       int i;
-       for (i=0; (i<im->sy); i++) {
-               free(im->pixels[i]);
-       }       
-       free(im->pixels);
-       if (im->polyInts) {
-                       free(im->polyInts);
-       }
-       if (im->style) {
-               free(im->style);
-       }
-       free(im);
-}
-
-int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
-{
-       int i;
-       long rd, gd, bd;
-       int ct = (-1);
-       long mindist = 0;
-       for (i=0; (i<(im->colorsTotal)); i++) {
-               long dist;
-               if (im->open[i]) {
-                       continue;
-               }
-               rd = (im->red[i] - r);  
-               gd = (im->green[i] - g);
-               bd = (im->blue[i] - b);
-               dist = rd * rd + gd * gd + bd * bd;
-               if ((i == 0) || (dist < mindist)) {
-                       mindist = dist; 
-                       ct = i;
-               }
-       }
-       return ct;
-}
-
-int gdImageColorExact(gdImagePtr im, int r, int g, int b)
-{
-       int i;
-       for (i=0; (i<(im->colorsTotal)); i++) {
-               if (im->open[i]) {
-                       continue;
-               }
-               if ((im->red[i] == r) && 
-                       (im->green[i] == g) &&
-                       (im->blue[i] == b)) {
-                       return i;
-               }
-       }
-       return -1;
-}
-
-int gdImageColorAllocate(gdImagePtr im, int r, int g, int b)
-{
-       int i;
-       int ct = (-1);
-       for (i=0; (i<(im->colorsTotal)); i++) {
-               if (im->open[i]) {
-                       ct = i;
-                       break;
-               }
-       }       
-       if (ct == (-1)) {
-               ct = im->colorsTotal;
-               if (ct == gdMaxColors) {
-                       return -1;
-               }
-               im->colorsTotal++;
-       }
-       im->red[ct] = r;
-       im->green[ct] = g;
-       im->blue[ct] = b;
-       im->open[ct] = 0;
-       return ct;
-}
-
-void gdImageColorDeallocate(gdImagePtr im, int color)
-{
-       /* Mark it open. */
-       im->open[color] = 1;
-}
-
-void gdImageColorTransparent(gdImagePtr im, int color)
-{
-       im->transparent = color;
-}
-
-void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
-{
-       int p;
-       switch(color) {
-               case gdStyled:
-               if (!im->style) {
-                       /* Refuse to draw if no style is set. */
-                       return;
-               } else {
-                       p = im->style[im->stylePos++];
-               }
-               if (p != (gdTransparent)) {
-                       gdImageSetPixel(im, x, y, p);
-               }
-               im->stylePos = im->stylePos %  im->styleLength;
-               break;
-               case gdStyledBrushed:
-               if (!im->style) {
-                       /* Refuse to draw if no style is set. */
-                       return;
-               }
-               p = im->style[im->stylePos++];
-               if ((p != gdTransparent) && (p != 0)) {
-                       gdImageSetPixel(im, x, y, gdBrushed);
-               }
-               im->stylePos = im->stylePos %  im->styleLength;
-               break;
-               case gdBrushed:
-               gdImageBrushApply(im, x, y);
-               break;
-               case gdTiled:
-               gdImageTileApply(im, x, y);
-               break;
-               default:
-               if (gdImageBoundsSafe(im, x, y)) {
-                       /* NOW ROW-MAJOR IN GD 1.3 */
-                       im->pixels[y][x] = color;
-               }
-               break;
-       }
-}
-
-static void gdImageBrushApply(gdImagePtr im, int x, int y)
-{
-       int lx, ly;
-       int hy;
-       int hx;
-       int x1, y1, x2, y2;
-       int srcx, srcy;
-       if (!im->brush) {
-               return;
-       }
-       hy = gdImageSY(im->brush)/2;
-       y1 = y - hy;
-       y2 = y1 + gdImageSY(im->brush); 
-       hx = gdImageSX(im->brush)/2;
-       x1 = x - hx;
-       x2 = x1 + gdImageSX(im->brush);
-       srcy = 0;
-       for (ly = y1; (ly < y2); ly++) {
-               srcx = 0;
-               for (lx = x1; (lx < x2); lx++) {
-                       int p;
-                       p = gdImageGetPixel(im->brush, srcx, srcy);
-                       /* Allow for non-square brushes! */
-                       if (p != gdImageGetTransparent(im->brush)) {
-                               gdImageSetPixel(im, lx, ly,
-                                       im->brushColorMap[p]);
-                       }
-                       srcx++;
-               }
-               srcy++;
-       }       
-}              
-
-static void gdImageTileApply(gdImagePtr im, int x, int y)
-{
-       int srcx, srcy;
-       int p;
-       if (!im->tile) {
-               return;
-       }
-       srcx = x % gdImageSX(im->tile);
-       srcy = y % gdImageSY(im->tile);
-       p = gdImageGetPixel(im->tile, srcx, srcy);
-       /* Allow for transparency */
-       if (p != gdImageGetTransparent(im->tile)) {
-               gdImageSetPixel(im, x, y,
-                       im->tileColorMap[p]);
-       }
-}              
-
-int gdImageGetPixel(gdImagePtr im, int x, int y)
-{
-       if (gdImageBoundsSafe(im, x, y)) {
-               /* NOW ROW-MAJOR IN GD 1.3 */
-               return im->pixels[y][x];
-       } else {
-               return 0;
-       }
-}
-
-/* Bresenham as presented in Foley & Van Dam */
-
-void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
-{
-       int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
-       dx = abs(x2-x1);
-       dy = abs(y2-y1);
-       if (dy <= dx) {
-               d = 2*dy - dx;
-               incr1 = 2*dy;
-               incr2 = 2 * (dy - dx);
-               if (x1 > x2) {
-                       x = x2;
-                       y = y2;
-                       ydirflag = (-1);
-                       xend = x1;
-               } else {
-                       x = x1;
-                       y = y1;
-                       ydirflag = 1;
-                       xend = x2;
-               }
-               gdImageSetPixel(im, x, y, color);
-               if (((y2 - y1) * ydirflag) > 0) {
-                       while (x < xend) {
-                               x++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       y++;
-                                       d+=incr2;
-                               }
-                               gdImageSetPixel(im, x, y, color);
-                       }
-               } else {
-                       while (x < xend) {
-                               x++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       y--;
-                                       d+=incr2;
-                               }
-                               gdImageSetPixel(im, x, y, color);
-                       }
-               }               
-       } else {
-               d = 2*dx - dy;
-               incr1 = 2*dx;
-               incr2 = 2 * (dx - dy);
-               if (y1 > y2) {
-                       y = y2;
-                       x = x2;
-                       yend = y1;
-                       xdirflag = (-1);
-               } else {
-                       y = y1;
-                       x = x1;
-                       yend = y2;
-                       xdirflag = 1;
-               }
-               gdImageSetPixel(im, x, y, color);
-               if (((x2 - x1) * xdirflag) > 0) {
-                       while (y < yend) {
-                               y++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       x++;
-                                       d+=incr2;
-                               }
-                               gdImageSetPixel(im, x, y, color);
-                       }
-               } else {
-                       while (y < yend) {
-                               y++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       x--;
-                                       d+=incr2;
-                               }
-                               gdImageSetPixel(im, x, y, color);
-                       }
-               }
-       }
-}
-
-static void dashedSet(gdImagePtr im, int x, int y, int color,
-       int *onP, int *dashStepP);
-
-void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
-{
-       int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
-       int dashStep = 0;
-       int on = 1;
-       dx = abs(x2-x1);
-       dy = abs(y2-y1);
-       if (dy <= dx) {
-               d = 2*dy - dx;
-               incr1 = 2*dy;
-               incr2 = 2 * (dy - dx);
-               if (x1 > x2) {
-                       x = x2;
-                       y = y2;
-                       ydirflag = (-1);
-                       xend = x1;
-               } else {
-                       x = x1;
-                       y = y1;
-                       ydirflag = 1;
-                       xend = x2;
-               }
-               dashedSet(im, x, y, color, &on, &dashStep);
-               if (((y2 - y1) * ydirflag) > 0) {
-                       while (x < xend) {
-                               x++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       y++;
-                                       d+=incr2;
-                               }
-                               dashedSet(im, x, y, color, &on, &dashStep);
-                       }
-               } else {
-                       while (x < xend) {
-                               x++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       y--;
-                                       d+=incr2;
-                               }
-                               dashedSet(im, x, y, color, &on, &dashStep);
-                       }
-               }               
-       } else {
-               d = 2*dx - dy;
-               incr1 = 2*dx;
-               incr2 = 2 * (dx - dy);
-               if (y1 > y2) {
-                       y = y2;
-                       x = x2;
-                       yend = y1;
-                       xdirflag = (-1);
-               } else {
-                       y = y1;
-                       x = x1;
-                       yend = y2;
-                       xdirflag = 1;
-               }
-               dashedSet(im, x, y, color, &on, &dashStep);
-               if (((x2 - x1) * xdirflag) > 0) {
-                       while (y < yend) {
-                               y++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       x++;
-                                       d+=incr2;
-                               }
-                               dashedSet(im, x, y, color, &on, &dashStep);
-                       }
-               } else {
-                       while (y < yend) {
-                               y++;
-                               if (d <0) {
-                                       d+=incr1;
-                               } else {
-                                       x--;
-                                       d+=incr2;
-                               }
-                               dashedSet(im, x, y, color, &on, &dashStep);
-                       }
-               }
-       }
-}
-
-static void dashedSet(gdImagePtr im, int x, int y, int color,
-       int *onP, int *dashStepP)
-{
-       int dashStep = *dashStepP;
-       int on = *onP;
-       dashStep++;
-       if (dashStep == gdDashSize) {
-               dashStep = 0;
-               on = !on;
-       }
-       if (on) {
-               gdImageSetPixel(im, x, y, color);
-       }
-       *dashStepP = dashStep;
-       *onP = on;
-}
-       
-
-int gdImageBoundsSafe(gdImagePtr im, int x, int y)
-{
-       return (!(((y < 0) || (y >= im->sy)) ||
-               ((x < 0) || (x >= im->sx))));
-}
-
-void gdImageChar(gdImagePtr im, gdFontPtr f, int x, int y, 
-       int c, int color)
-{
-       int cx, cy;
-       int px, py;
-       int fline;
-       cx = 0;
-       cy = 0;
-       if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
-               return;
-       }
-       fline = (c - f->offset) * f->h * f->w;
-       for (py = y; (py < (y + f->h)); py++) {
-               for (px = x; (px < (x + f->w)); px++) {
-                       if (f->data[fline + cy * f->w + cx]) {
-                               gdImageSetPixel(im, px, py, color);     
-                       }
-                       cx++;
-               }
-               cx = 0;
-               cy++;
-       }
-}
-
-void gdImageCharUp(gdImagePtr im, gdFontPtr f, 
-       int x, int y, int c, int color)
-{
-       int cx, cy;
-       int px, py;
-       int fline;
-       cx = 0;
-       cy = 0;
-       if ((c < f->offset) || (c >= (f->offset + f->nchars))) {
-               return;
-       }
-       fline = (c - f->offset) * f->h * f->w;
-       for (py = y; (py > (y - f->w)); py--) {
-               for (px = x; (px < (x + f->h)); px++) {
-                       if (f->data[fline + cy * f->w + cx]) {
-                               gdImageSetPixel(im, px, py, color);     
-                       }
-                       cy++;
-               }
-               cy = 0;
-               cx++;
-       }
-}
-
-void gdImageString(gdImagePtr im, gdFontPtr f, 
-       int x, int y, unsigned char *s, int color)
-{
-       int i;
-       int l;
-       l = strlen(s);
-       for (i=0; (i<l); i++) {
-               gdImageChar(im, f, x, y, s[i], color);
-               x += f->w;
-       }
-}
-
-void gdImageStringUp(gdImagePtr im, gdFontPtr f, 
-       int x, int y, unsigned char *s, int color)
-{
-       int i;
-       int l;
-       l = strlen(s);
-       for (i=0; (i<l); i++) {
-               gdImageCharUp(im, f, x, y, s[i], color);
-               y -= f->w;
-       }
-}
-
-static int strlen16(unsigned short *s);
-
-void gdImageString16(gdImagePtr im, gdFontPtr f, 
-       int x, int y, unsigned short *s, int color)
-{
-       int i;
-       int l;
-       l = strlen16(s);
-       for (i=0; (i<l); i++) {
-               gdImageChar(im, f, x, y, s[i], color);
-               x += f->w;
-       }
-}
-
-void gdImageStringUp16(gdImagePtr im, gdFontPtr f, 
-       int x, int y, unsigned short *s, int color)
-{
-       int i;
-       int l;
-       l = strlen16(s);
-       for (i=0; (i<l); i++) {
-               gdImageCharUp(im, f, x, y, s[i], color);
-               y -= f->w;
-       }
-}
-
-static int strlen16(unsigned short *s)
-{
-       int len = 0;
-       while (*s) {
-               s++;
-               len++;
-       }
-       return len;
-}
-
-/* s and e are integers modulo 360 (degrees), with 0 degrees
-  being the rightmost extreme and degrees changing clockwise.
-  cx and cy are the center in pixels; w and h are the horizontal 
-  and vertical diameter in pixels. Nice interface, but slow, since
-  I don't yet use Bresenham (I'm using an inefficient but
-  simple solution with too much work going on in it; generalizing
-  Bresenham to ellipses and partial arcs of ellipses is non-trivial,
-  at least for me) and there are other inefficiencies (small circles
-  do far too much work). */
-
-void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color)
-{
-       int i;
-       int lx = 0, ly = 0;
-       int w2, h2;
-       w2 = w/2;
-       h2 = h/2;
-       while (e < s) {
-               e += 360;
-       }
-       for (i=s; (i <= e); i++) {
-               int x, y;
-               x = ((long)cost[i % 360] * (long)w2 / costScale) + cx; 
-               y = ((long)sint[i % 360] * (long)h2 / sintScale) + cy;
-               if (i != s) {
-                       gdImageLine(im, lx, ly, x, y, color);   
-               }
-               lx = x;
-               ly = y;
-       }
-}
-
-
-#if 0
-       /* Bresenham octant code, which I should use eventually */
-       int x, y, d;
-       x = 0;
-       y = w;
-       d = 3-2*w;
-       while (x < y) {
-               gdImageSetPixel(im, cx+x, cy+y, color);
-               if (d < 0) {
-                       d += 4 * x + 6;
-               } else {
-                       d += 4 * (x - y) + 10;
-                       y--;
-               }
-               x++;
-       }
-       if (x == y) {
-               gdImageSetPixel(im, cx+x, cy+y, color);
-       }
-#endif
-
-void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color)
-{
-       int lastBorder;
-       /* Seek left */
-       int leftLimit, rightLimit;
-       int i;
-       leftLimit = (-1);
-       if (border < 0) {
-               /* Refuse to fill to a non-solid border */
-               return;
-       }
-       for (i = x; (i >= 0); i--) {
-               if (gdImageGetPixel(im, i, y) == border) {
-                       break;
-               }
-               gdImageSetPixel(im, i, y, color);
-               leftLimit = i;
-       }
-       if (leftLimit == (-1)) {
-               return;
-       }
-       /* Seek right */
-       rightLimit = x;
-       for (i = (x+1); (i < im->sx); i++) {    
-               if (gdImageGetPixel(im, i, y) == border) {
-                       break;
-               }
-               gdImageSetPixel(im, i, y, color);
-               rightLimit = i;
-       }
-       /* Look at lines above and below and start paints */
-       /* Above */
-       if (y > 0) {
-               lastBorder = 1;
-               for (i = leftLimit; (i <= rightLimit); i++) {
-                       int c;
-                       c = gdImageGetPixel(im, i, y-1);
-                       if (lastBorder) {
-                               if ((c != border) && (c != color)) {    
-                                       gdImageFillToBorder(im, i, y-1, 
-                                               border, color);         
-                                       lastBorder = 0;
-                               }
-                       } else if ((c == border) || (c == color)) {
-                               lastBorder = 1;
-                       }
-               }
-       }
-       /* Below */
-       if (y < ((im->sy) - 1)) {
-               lastBorder = 1;
-               for (i = leftLimit; (i <= rightLimit); i++) {
-                       int c;
-                       c = gdImageGetPixel(im, i, y+1);
-                       if (lastBorder) {
-                               if ((c != border) && (c != color)) {    
-                                       gdImageFillToBorder(im, i, y+1, 
-                                               border, color);         
-                                       lastBorder = 0;
-                               }
-                       } else if ((c == border) || (c == color)) {
-                               lastBorder = 1;
-                       }
-               }
-       }
-}
-
-void gdImageFill(gdImagePtr im, int x, int y, int color)
-{
-       int lastBorder;
-       int old;
-       int leftLimit, rightLimit;
-       int i;
-       old = gdImageGetPixel(im, x, y);
-       if (color == gdTiled) {
-               /* Tile fill -- got to watch out! */
-               int p, tileColor;       
-               int srcx, srcy;
-               if (!im->tile) {
-                       return;
-               }
-               /* Refuse to flood-fill with a transparent pattern --
-                       I can't do it without allocating another image */
-               if (gdImageGetTransparent(im->tile) != (-1)) {
-                       return;
-               }       
-               srcx = x % gdImageSX(im->tile);
-               srcy = y % gdImageSY(im->tile);
-               p = gdImageGetPixel(im->tile, srcx, srcy);
-               tileColor = im->tileColorMap[p];
-               if (old == tileColor) {
-                       /* Nothing to be done */
-                       return;
-               }
-       } else {
-               if (old == color) {
-                       /* Nothing to be done */
-                       return;
-               }
-       }
-       /* Seek left */
-       leftLimit = (-1);
-       for (i = x; (i >= 0); i--) {
-               if (gdImageGetPixel(im, i, y) != old) {
-                       break;
-               }
-               gdImageSetPixel(im, i, y, color);
-               leftLimit = i;
-       }
-       if (leftLimit == (-1)) {
-               return;
-       }
-       /* Seek right */
-       rightLimit = x;
-       for (i = (x+1); (i < im->sx); i++) {    
-               if (gdImageGetPixel(im, i, y) != old) {
-                       break;
-               }
-               gdImageSetPixel(im, i, y, color);
-               rightLimit = i;
-       }
-       /* Look at lines above and below and start paints */
-       /* Above */
-       if (y > 0) {
-               lastBorder = 1;
-               for (i = leftLimit; (i <= rightLimit); i++) {
-                       int c;
-                       c = gdImageGetPixel(im, i, y-1);
-                       if (lastBorder) {
-                               if (c == old) { 
-                                       gdImageFill(im, i, y-1, color);         
-                                       lastBorder = 0;
-                               }
-                       } else if (c != old) {
-                               lastBorder = 1;
-                       }
-               }
-       }
-       /* Below */
-       if (y < ((im->sy) - 1)) {
-               lastBorder = 1;
-               for (i = leftLimit; (i <= rightLimit); i++) {
-                       int c;
-                       c = gdImageGetPixel(im, i, y+1);
-                       if (lastBorder) {
-                               if (c == old) {
-                                       gdImageFill(im, i, y+1, color);         
-                                       lastBorder = 0;
-                               }
-                       } else if (c != old) {
-                               lastBorder = 1;
-                       }
-               }
-       }
-}
-       
-/* 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 (FILE *fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
-static void Putword (int w, FILE *fp);
-static void compress (int, FILE *, gdImagePtr, int);
-static void output (code_int code);
-/* Allows for reuse */
-static void init_statics(void);
-
-void gdImageGif(gdImagePtr im, FILE *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);
-}
-
-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(FILE *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
-         */
-        fwrite( Transparent < 0 ? "GIF87a" : "GIF89a", 1, 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) << 4;
-
-        /*
-         * OR in the Bits per Pixel
-         */
-        B |= (BitsPerPixel - 1);
-
-        /*
-         * Write it out
-         */
-        fputc( B, fp );
-
-        /*
-         * Write out the Background colour
-         */
-        fputc( Background, fp );
-
-        /*
-         * Byte of 0's (future expansion)
-         */
-        fputc( 0, fp );
-
-        /*
-         * Write out the Global Colour Map
-         */
-        for( i=0; i<ColorMapSize; ++i ) {
-                fputc( Red[i], fp );
-                fputc( Green[i], fp );
-                fputc( Blue[i], fp );
-        }
-
-       /*
-        * Write out extension for transparent colour index, if necessary.
-        */
-       if ( Transparent >= 0 ) {
-           fputc( '!', fp );
-           fputc( 0xf9, fp );
-           fputc( 4, fp );
-           fputc( 1, fp );
-           fputc( 0, fp );
-           fputc( 0, fp );
-           fputc( (unsigned char) Transparent, fp );
-           fputc( 0, fp );
-       }
-
-        /*
-         * Write an Image separator
-         */
-        fputc( ',', 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 )
-                fputc( 0x40, fp );
-        else
-                fputc( 0x00, fp );
-
-        /*
-         * Write out the initial code size
-         */
-        fputc( InitCodeSize, fp );
-
-        /*
-         * Go and actually compress the data
-         */
-        compress( InitCodeSize+1, fp, im, Background );
-
-        /*
-         * Write out a Zero-length packet (to end the series)
-         */
-        fputc( 0, fp );
-
-        /*
-         * Write the GIF file terminator
-         */
-        fputc( ';', fp );
-}
-
-/*
- * Write out a word to the GIF file
- */
-static void
-Putword(int w, FILE *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 FILE *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");
-  }
- fputc(oblen,ofile);
- fwrite(&oblock[0],1,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 ncost;
-
- ncost = 0;
- perrep = (nrepcodes * (nrepcodes+1)) / 2;
- while (count >= perrep)
-  { ncost += 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 ++;
-    ncost += n;
-  }
- return(ncost);
-}
-
-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)
-{
-
- 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 compress(int init_bits, FILE *outfile, gdImagePtr im, int background)
-{
- 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;
-
-/*
- * Define the storage for the packet accumulator
- */
-
-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.           | */
-/* +-------------------------------------------------------------------+ */
-
-
-#define        MAXCOLORMAPSIZE         256
-
-#define        TRUE    1
-#define        FALSE   0
-
-#define CM_RED         0
-#define CM_GREEN       1
-#define CM_BLUE                2
-
-#define        MAX_LWZ_BITS            12
-
-#define INTERLACE              0x40
-#define LOCALCOLORMAP  0x80
-#define BitSet(byte, bit)      (((byte) & (bit)) == (bit))
-
-#define        ReadOK(file,buffer,len) (fread(buffer, len, 1, file) != 0)
-
-#define LM_to_uint(a,b)                        (((b)<<8)|(a))
-
-/* We may eventually want to use this information, but def it out for now */
-#if 0
-static struct {
-       unsigned int    Width;
-       unsigned int    Height;
-       unsigned char   ColorMap[3][MAXCOLORMAPSIZE];
-       unsigned int    BitPixel;
-       unsigned int    ColorResolution;
-       unsigned int    Background;
-       unsigned int    AspectRatio;
-} GifScreen;
-#endif
-
-int ZeroDataBlock;
-
-
-void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
-{
-       gdImageLine(im, x1, y1, x2, y1, color);         
-       gdImageLine(im, x1, y2, x2, y2, color);         
-       gdImageLine(im, x1, y1, x1, y2, color);
-       gdImageLine(im, x2, y1, x2, y2, color);
-}
-
-void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int y2, int color)
-{
-       int x, y;
-       for (y=y1; (y<=y2); y++) {
-               for (x=x1; (x<=x2); x++) {
-                       gdImageSetPixel(im, x, y, color);
-               }
-       }
-}
-
-void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
-{
-       int c;
-       int x, y;
-       int tox, toy;
-       int i;
-       int colorMap[gdMaxColors];
-       for (i=0; (i<gdMaxColors); i++) {
-               colorMap[i] = (-1);
-       }
-       toy = dstY;
-       for (y=srcY; (y < (srcY + h)); y++) {
-               tox = dstX;
-               for (x=srcX; (x < (srcX + w)); x++) {
-                       int nc;
-                       c = gdImageGetPixel(src, x, y);
-                       /* Added 7/24/95: support transparent copies */
-                       if (gdImageGetTransparent(src) == c) {
-                               tox++;
-                               continue;
-                       }
-                       /* Have we established a mapping for this color? */
-                       if (colorMap[c] == (-1)) {
-                               /* If it's the same image, mapping is trivial */
-                               if (dst == src) {
-                                       nc = c;
-                               } else { 
-                                       /* First look for an exact match */
-                                       nc = gdImageColorExact(dst,
-                                               src->red[c], src->green[c],
-                                               src->blue[c]);
-                               }       
-                               if (nc == (-1)) {
-                                       /* No, so try to allocate it */
-                                       nc = gdImageColorAllocate(dst,
-                                               src->red[c], src->green[c],
-                                               src->blue[c]);
-                                       /* If we're out of colors, go for the
-                                               closest color */
-                                       if (nc == (-1)) {
-                                               nc = gdImageColorClosest(dst,
-                                                       src->red[c], src->green[c],
-                                                       src->blue[c]);
-                                       }
-                               }
-                               colorMap[c] = nc;
-                       }
-                       gdImageSetPixel(dst, tox, toy, colorMap[c]);
-                       tox++;
-               }
-               toy++;
-       }
-}                      
-
-void gdImageCopyResized(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH)
-{
-       int c;
-       int x, y;
-       int tox, toy;
-       int ydest;
-       int i;
-       int colorMap[gdMaxColors];
-       /* Stretch vectors */
-       int *stx;
-       int *sty;
-       /* We only need to use floating point to determine the correct
-               stretch vector for one line's worth. */
-       double accum;
-       stx = (int *) malloc(sizeof(int) * srcW);
-       sty = (int *) malloc(sizeof(int) * srcH);
-       accum = 0;
-       for (i=0; (i < srcW); i++) {
-               int got;
-               accum += (double)dstW/(double)srcW;
-               got = floor(accum);
-               stx[i] = got;
-               accum -= got;
-       }
-       accum = 0;
-       for (i=0; (i < srcH); i++) {
-               int got;
-               accum += (double)dstH/(double)srcH;
-               got = floor(accum);
-               sty[i] = got;
-               accum -= got;
-       }
-       for (i=0; (i<gdMaxColors); i++) {
-               colorMap[i] = (-1);
-       }
-       toy = dstY;
-       for (y=srcY; (y < (srcY + srcH)); y++) {
-               for (ydest=0; (ydest < sty[y-srcY]); ydest++) {
-                       tox = dstX;
-                       for (x=srcX; (x < (srcX + srcW)); x++) {
-                               int nc;
-                               if (!stx[x - srcX]) {
-                                       continue;
-                               }
-                               c = gdImageGetPixel(src, x, y);
-                               /* Added 7/24/95: support transparent copies */
-                               if (gdImageGetTransparent(src) == c) {
-                                       tox += stx[x-srcX];
-                                       continue;
-                               }
-                               /* Have we established a mapping for this color? */
-                               if (colorMap[c] == (-1)) {
-                                       /* If it's the same image, mapping is trivial */
-                                       if (dst == src) {
-                                               nc = c;
-                                       } else { 
-                                               /* First look for an exact match */
-                                               nc = gdImageColorExact(dst,
-                                                       src->red[c], src->green[c],
-                                                       src->blue[c]);
-                                       }       
-                                       if (nc == (-1)) {
-                                               /* No, so try to allocate it */
-                                               nc = gdImageColorAllocate(dst,
-                                                       src->red[c], src->green[c],
-                                                       src->blue[c]);
-                                               /* If we're out of colors, go for the
-                                                       closest color */
-                                               if (nc == (-1)) {
-                                                       nc = gdImageColorClosest(dst,
-                                                               src->red[c], src->green[c],
-                                                               src->blue[c]);
-                                               }
-                                       }
-                                       colorMap[c] = nc;
-                               }
-                               for (i=0; (i < stx[x - srcX]); i++) {
-                                       gdImageSetPixel(dst, tox, toy, colorMap[c]);
-                                       tox++;
-                               }
-                       }
-                       toy++;
-               }
-       }
-       free(stx);
-       free(sty);
-}
-
-int gdGetWord(int *result, FILE *in)
-{
-       int r;
-       r = getc(in);
-       if (r == EOF) {
-               return 0;
-       }
-       *result = r << 8;
-       r = getc(in);   
-       if (r == EOF) {
-               return 0;
-       }
-       *result += r;
-       return 1;
-}
-
-void gdPutWord(int w, FILE *out)
-{
-       putc((unsigned char)(w >> 8), out);
-       putc((unsigned char)(w & 0xFF), out);
-}
-
-int gdGetByte(int *result, FILE *in)
-{
-       int r;
-       r = getc(in);
-       if (r == EOF) {
-               return 0;
-       }
-       *result = r;
-       return 1;
-}
-
-gdImagePtr gdImageCreateFromGd(FILE *in)
-{
-       int sx, sy;
-       int x, y;
-       int i;
-       gdImagePtr im;
-       if (!gdGetWord(&sx, in)) {
-               goto fail1;
-       }
-       if (!gdGetWord(&sy, in)) {
-               goto fail1;
-       }
-       im = gdImageCreate(sx, sy);
-       if (!gdGetByte(&im->colorsTotal, in)) {
-               goto fail2;
-       }
-       if (!gdGetWord(&im->transparent, in)) {
-               goto fail2;
-       }
-       if (im->transparent == 257) {
-               im->transparent = (-1);
-       }
-       for (i=0; (i<gdMaxColors); i++) {
-               if (!gdGetByte(&im->red[i], in)) {
-                       goto fail2;
-               }
-               if (!gdGetByte(&im->green[i], in)) {
-                       goto fail2;
-               }
-               if (!gdGetByte(&im->blue[i], in)) {
-                       goto fail2;
-               }
-       }       
-       for (y=0; (y<sy); y++) {
-               for (x=0; (x<sx); x++) {        
-                       int ch;
-                       ch = getc(in);
-                       if (ch == EOF) {
-                               gdImageDestroy(im);
-                               return 0;
-                       }
-                       /* ROW-MAJOR IN GD 1.3 */
-                       im->pixels[y][x] = ch;
-               }
-       }
-       return im;
-fail2:
-       gdImageDestroy(im);
-fail1:
-       return 0;
-}
-       
-void gdImageGd(gdImagePtr im, FILE *out)
-{
-       int x, y;
-       int i;
-       int trans;
-       gdPutWord(im->sx, out);
-       gdPutWord(im->sy, out);
-       putc((unsigned char)im->colorsTotal, out);
-       trans = im->transparent;
-       if (trans == (-1)) {
-               trans = 257;
-       }       
-       gdPutWord(trans, out);
-       for (i=0; (i<gdMaxColors); i++) {
-               putc((unsigned char)im->red[i], out);
-               putc((unsigned char)im->green[i], out); 
-               putc((unsigned char)im->blue[i], out);  
-       }
-       for (y=0; (y < im->sy); y++) {  
-               for (x=0; (x < im->sx); x++) {  
-                       /* ROW-MAJOR IN GD 1.3 */
-                       putc((unsigned char)im->pixels[y][x], out);
-               }
-       }
-}
-
-gdImagePtr
-gdImageCreateFromXbm(FILE *fd)
-{
-       gdImagePtr im;  
-       int bit;
-       int w, h;
-       int bytes;
-       int ch;
-       int i, x, y;
-       char *sp;
-       char s[161];
-       if (!fgets(s, 160, fd)) {
-               return 0;
-       }
-       sp = &s[0];
-       /* Skip #define */
-       sp = strchr(sp, ' ');
-       if (!sp) {
-               return 0;
-       }
-       /* Skip width label */
-       sp++;
-       sp = strchr(sp, ' ');
-       if (!sp) {
-               return 0;
-       }
-       /* Get width */
-       w = atoi(sp + 1);
-       if (!w) {
-               return 0;
-       }
-       if (!fgets(s, 160, fd)) {
-               return 0;
-       }
-       sp = s;
-       /* Skip #define */
-       sp = strchr(sp, ' ');
-       if (!sp) {
-               return 0;
-       }
-       /* Skip height label */
-       sp++;
-       sp = strchr(sp, ' ');
-       if (!sp) {
-               return 0;
-       }
-       /* Get height */
-       h = atoi(sp + 1);
-       if (!h) {
-               return 0;
-       }
-       /* Skip declaration line */
-       if (!fgets(s, 160, fd)) {
-               return 0;
-       }
-       bytes = (w * h / 8) + 1;
-       im = gdImageCreate(w, h);
-       gdImageColorAllocate(im, 255, 255, 255);
-       gdImageColorAllocate(im, 0, 0, 0);
-       x = 0;
-       y = 0;
-       for (i=0; (i < bytes); i++) {
-               char h[3];
-               int b;
-               /* Skip spaces, commas, CRs, 0x */
-               while(1) {
-                       ch = getc(fd);
-                       if (ch == EOF) {
-                               goto fail;
-                       }
-                       if (ch == 'x') {
-                               break;
-                       }       
-               }
-               /* Get hex value */
-               ch = getc(fd);
-               if (ch == EOF) {
-                       goto fail;
-               }
-               h[0] = ch;
-               ch = getc(fd);
-               if (ch == EOF) {
-                       goto fail;
-               }
-               h[1] = ch;
-               h[2] = '\0';
-               sscanf(h, "%x", &b);            
-               for (bit = 1; (bit <= 128); (bit = bit << 1)) {
-                       gdImageSetPixel(im, x++, y, (b & bit) ? 1 : 0); 
-                       if (x == im->sx) {
-                               x = 0;
-                               y++;
-                               if (y == im->sy) {
-                                       return im;
-                               }
-                               /* Fix 8/8/95 */
-                               break;
-                       }
-               }
-       }
-       /* Shouldn't happen */
-       fprintf(stderr, "Error: bug in gdImageCreateFromXbm!\n");
-       return 0;
-fail:
-       gdImageDestroy(im);
-       return 0;
-}
-
-void gdImagePolygon(gdImagePtr im, gdPointPtr p, int n, int c)
-{
-       int i;
-       int lx, ly;
-       if (!n) {
-               return;
-       }
-       lx = p->x;
-       ly = p->y;
-       gdImageLine(im, lx, ly, p[n-1].x, p[n-1].y, c);
-       for (i=1; (i < n); i++) {
-               p++;
-               gdImageLine(im, lx, ly, p->x, p->y, c);
-               lx = p->x;
-               ly = p->y;
-       }
-}      
-       
-int gdCompareInt(const void *a, const void *b);
-       
-void gdImageFilledPolygon(gdImagePtr im, gdPointPtr p, int n, int c)
-{
-       int i;
-       int y;
-       int y1, y2;
-       int ints;
-       if (!n) {
-               return;
-       }
-       if (!im->polyAllocated) {
-               im->polyInts = (int *) malloc(sizeof(int) * n);
-               im->polyAllocated = n;
-       }               
-       if (im->polyAllocated < n) {
-               while (im->polyAllocated < n) {
-                       im->polyAllocated *= 2;
-               }       
-               im->polyInts = (int *) realloc(im->polyInts,
-                       sizeof(int) * im->polyAllocated);
-       }
-       y1 = p[0].y;
-       y2 = p[0].y;
-       for (i=1; (i < n); i++) {
-               if (p[i].y < y1) {
-                       y1 = p[i].y;
-               }
-               if (p[i].y > y2) {
-                       y2 = p[i].y;
-               }
-       }
-       /* Fix in 1.3: count a vertex only once */
-       for (y=y1; (y < y2); y++) {
-               int interLast = 0;
-               int dirLast = 0;
-               int interFirst = 1;
-               ints = 0;
-               for (i=0; (i <= n); i++) {
-                       int x1, x2;
-                       int y1, y2;
-                       int dir;
-                       int ind1, ind2;
-                       int lastInd1 = 0;
-                       if ((i == n) || (!i)) {
-                               ind1 = n-1;
-                               ind2 = 0;
-                       } else {
-                               ind1 = i-1;
-                               ind2 = i;
-                       }
-                       y1 = p[ind1].y;
-                       y2 = p[ind2].y;
-                       if (y1 < y2) {
-                               y1 = p[ind1].y;
-                               y2 = p[ind2].y;
-                               x1 = p[ind1].x;
-                               x2 = p[ind2].x;
-                               dir = -1;
-                       } else if (y1 > y2) {
-                               y2 = p[ind1].y;
-                               y1 = p[ind2].y;
-                               x2 = p[ind1].x;
-                               x1 = p[ind2].x;
-                               dir = 1;
-                       } else {
-                               /* Horizontal; just draw it */
-                               gdImageLine(im, 
-                                       p[ind1].x, y1, 
-                                       p[ind2].x, y1,
-                                       c);
-                               continue;
-                       }
-                       if ((y >= y1) && (y <= y2)) {
-                               int inter = 
-                                       (y-y1) * (x2-x1) / (y2-y1) + x1;
-                               /* Only count intersections once
-                                       except at maxima and minima. Also, 
-                                       if two consecutive intersections are
-                                       endpoints of the same horizontal line
-                                       that is not at a maxima or minima,      
-                                       discard the leftmost of the two. */
-                               if (!interFirst) {
-                                       if ((p[ind1].y == p[lastInd1].y) &&
-                                               (p[ind1].x != p[lastInd1].x)) {
-                                               if (dir == dirLast) {
-                                                       if (inter > interLast) {
-                                                               /* Replace the old one */
-                                                               im->polyInts[ints] = inter;
-                                                       } else {
-                                                               /* Discard this one */
-                                                       }       
-                                                       continue;
-                                               }
-                                       }
-                                       if (inter == interLast) {
-                                               if (dir == dirLast) {
-                                                       continue;
-                                               }
-                                       }
-                               } 
-                               if (i > 0) {
-                                       im->polyInts[ints++] = inter;
-                               }
-                               lastInd1 = i;
-                               dirLast = dir;
-                               interLast = inter;
-                               interFirst = 0;
-                       }
-               }
-               qsort(im->polyInts, ints, sizeof(int), gdCompareInt);
-               for (i=0; (i < (ints-1)); i+=2) {
-                       gdImageLine(im, im->polyInts[i], y,
-                               im->polyInts[i+1], y, c);
-               }
-       }
-}
-       
-int gdCompareInt(const void *a, const void *b)
-{
-       return (*(const int *)a) - (*(const int *)b);
-}
-
-void gdImageSetStyle(gdImagePtr im, int *style, int noOfPixels)
-{
-       if (im->style) {
-               free(im->style);
-       }
-       im->style = (int *) 
-               malloc(sizeof(int) * noOfPixels);
-       memcpy(im->style, style, sizeof(int) * noOfPixels);
-       im->styleLength = noOfPixels;
-       im->stylePos = 0;
-}
-
-void gdImageSetBrush(gdImagePtr im, gdImagePtr brush)
-{
-       int i;
-       im->brush = brush;
-       for (i=0; (i < gdImageColorsTotal(brush)); i++) {
-               int index;
-               index = gdImageColorExact(im, 
-                       gdImageRed(brush, i),
-                       gdImageGreen(brush, i),
-                       gdImageBlue(brush, i));
-               if (index == (-1)) {
-                       index = gdImageColorAllocate(im,
-                               gdImageRed(brush, i),
-                               gdImageGreen(brush, i),
-                               gdImageBlue(brush, i));
-                       if (index == (-1)) {
-                               index = gdImageColorClosest(im,
-                                       gdImageRed(brush, i),
-                                       gdImageGreen(brush, i),
-                                       gdImageBlue(brush, i));
-                       }
-               }
-               im->brushColorMap[i] = index;
-       }
-}
-       
-void gdImageSetTile(gdImagePtr im, gdImagePtr tile)
-{
-       int i;
-       im->tile = tile;
-       for (i=0; (i < gdImageColorsTotal(tile)); i++) {
-               int index;
-               index = gdImageColorExact(im, 
-                       gdImageRed(tile, i),
-                       gdImageGreen(tile, i),
-                       gdImageBlue(tile, i));
-               if (index == (-1)) {
-                       index = gdImageColorAllocate(im,
-                               gdImageRed(tile, i),
-                               gdImageGreen(tile, i),
-                               gdImageBlue(tile, i));
-                       if (index == (-1)) {
-                               index = gdImageColorClosest(im,
-                                       gdImageRed(tile, i),
-                                       gdImageGreen(tile, i),
-                                       gdImageBlue(tile, i));
-                       }
-               }
-               im->tileColorMap[i] = index;
-       }
-}
-
-void gdImageInterlace(gdImagePtr im, int interlaceArg)
-{
-       im->interlace = interlaceArg;
-}