Anonymous avatar Anonymous committed 1880992

- sync to 1.6.1

Comments (0)

Files changed (5)

+990718 Thomas Boutell (TBB)
+
+Incorporated Greg Roelofs' superior PNG read and write routines.
+
 990715 Thomas Boutell (TBB)
 
 Removed all GIF capability in favor of PNG
 void gdImageColorTransparent(gdImagePtr im, int color);
 void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src);
 void gdImagePng(gdImagePtr im, FILE *out);
+void gdImagePngCtx(gdImagePtr im, gdIOCtx *out);
 
 /* A custom data sink. */
 /* The sink function must return -1 on error, otherwise the number
 #define TRUE 1
 #define FALSE 0
 
-/* Exported functions */
-extern void gdImagePng(gdImagePtr im, FILE *out);
-extern gdImagePtr gdImageCreateFromPng(FILE *in);
+/*---------------------------------------------------------------------------
+    Routines taken from (and modified slightly from):
+
+    gdpng.c                                     Copyright 1999 Greg Roelofs
+
+    The routines in this file, gdImagePng() and gdImageCreateFromPng(), are
+    drop-in replacements for gdImageGif() and gdImageCreateFromGif(), except
+    that these functions are noisier in the case of errors (comment out all
+    fprintf() statements to disable that).
+
+    Only GIF-like PNG features are currently supported; that is, images must
+    be indexed-color (or they will be dithered in a fairly unattractive
+    fashion), and they can have, at most, a single, fully transparent
+    palette entry.  Since gd images are artificially generated, gamma is
+    ignored, and there is currently no support for embedded text annotations
+    (a la GIF comments).
+
+    Last updated:  15 July 1999
+
+  ---------------------------------------------------------------------------*/
+
+typedef struct _jmpbuf_wrapper {
+  jmp_buf jmpbuf;
+} jmpbuf_wrapper;
+
+static jmpbuf_wrapper gdPngJmpbufStruct;
+
+static void gdPngErrorHandler(png_structp png_ptr, png_const_charp msg);
+
+static void png_read_data(png_structp png_ptr, 
+	png_bytep data, png_size_t length)
+{
+	gdGetBuf(data, length, (gdIOCtx *)
+		png_get_io_ptr(png_ptr));	
+}
+
+static void png_write_data(png_structp png_ptr, 
+	png_bytep data, png_size_t length)
+{
+	gdPutBuf(data, length, (gdIOCtx *)
+		png_get_io_ptr(png_ptr));	
+}
+
+static void png_flush_data(png_structp png_ptr)
+{
+}
 
 gdImagePtr gdImageCreateFromPng(FILE *inFile)
 {
 	return im;
 }
 
-void png_read_data(png_structp png_ptr, 
-	png_bytep data, png_size_t length)
+/* This routine is based in part on the Chapter 13 demo code in "PNG: The
+ *  Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html).
+ */
+gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
 {
-	gdGetBuf(data, length, (gdIOCtx *)
-		png_get_io_ptr(png_ptr));	
-}
+    png_byte sig[8];
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_uint_32 width, height, rowbytes;
+    int bit_depth, color_type, interlace_type;
+    int num_palette, num_trans;
+    png_colorp palette;
+    png_bytep trans;
+    png_bytep image_data = NULL;
+    png_bytepp row_pointers = NULL;
+    gdImagePtr im = NULL;
+    int i, j, *open;
+    volatile int transparent = -1;
 
-gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in)
-{
-	gdImagePtr im;
-	png_structp png_ptr;
-	png_infop info_ptr;
-	int i;
-	png_ptr = malloc(sizeof(png_struct));
-	if (!png_ptr) {
-		return 0;
-	}
-	info_ptr = malloc(sizeof(png_info));
-	if (!info_ptr) {
-		return 0;
-	}	
-	if (setjmp(png_ptr->jmpbuf)) {
-		png_write_destroy(png_ptr);
-		free(png_ptr);
-		free(info_ptr);
-		return 0;
-	}
-	png_info_init(info_ptr);
-	png_read_init(png_ptr);
-	png_set_read_fn(png_ptr,
-		(void *) in,
-		png_read_data);
+    /* Make sure the signature can't match by dumb luck -- TBB */
+    memset(infile, 0, sizeof(infile));
+    /* first do a quick check that the file really is a PNG image; could
+     * have used slightly more general png_sig_cmp() function instead */
+    gdGetBuf(sig, 8, infile);
+    if (!png_check_sig(sig, 8))
+        return NULL;   /* bad signature */
+
+    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct,
+      gdPngErrorHandler, NULL);
+    if (png_ptr == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate libpng main struct\n");
+        return NULL;
+    }
+
+    info_ptr = png_create_info_struct(png_ptr);
+    if (info_ptr == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate libpng info struct\n");
+        png_destroy_read_struct(&png_ptr, NULL, NULL);
+        return NULL;
+    }
+
+    /* we could create a second info struct here (end_info), but it's only
+     * useful if we want to keep pre- and post-IDAT chunk info separated
+     * (mainly for PNG-aware image editors and converters) */
+
+    /* setjmp() must be called in every non-callback function that calls a
+     * PNG-reading libpng function */
+    if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
+        fprintf(stderr, "gd-png error: setjmp returns error condition\n");
+        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+        return NULL;
+    }
+    png_set_read_fn(png_ptr, (void *) infile, png_read_data);
+
+    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */
+
+    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */
+
+    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+      &interlace_type, NULL, NULL);
+    png_set_strip_16(png_ptr);
+    if (color_type != PNG_COLOR_TYPE_PALETTE) {
 	/* Turn non-palette PNGs into palette PNGs. This will
 		go away in a future 24-bit GD. It's not a very
 		good way of doing things. */
-	if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) {
-		png_colorp std_color_cube;
-		int r, g, b;
-		int i = 0;
-		std_color_cube = malloc(sizeof(png_color) * 216);
-		for (r = 0; (r < 6); r++) {
-			for (g = 0; (g < 6); g++) {
-				for (b = 0; (b < 6); b++) {
-					std_color_cube[i].red =
-						r * 51;
-					std_color_cube[i].green =
-						g * 51;
-					std_color_cube[i].blue =
-						b * 51;
-					i++;
-				}
+	png_colorp std_color_cube;
+	int r, g, b;
+	int i = 0;
+	std_color_cube = malloc(sizeof(png_color) * 216);
+	for (r = 0; (r < 6); r++) {
+		for (g = 0; (g < 6); g++) {
+			for (b = 0; (b < 6); b++) {
+				std_color_cube[i].red =
+					r * 51;
+				std_color_cube[i].green =
+					g * 51;
+				std_color_cube[i].blue =
+					b * 51;
+				i++;
 			}
 		}
-		png_set_dither(png_ptr, std_color_cube,
-			216, 216,
-			NULL, 0);
-	}
-	png_read_info(png_ptr, info_ptr);
-	if (info_ptr->valid &PNG_INFO_gAMA) {
-		png_set_gamma(png_ptr, 2.0, info_ptr->gamma);
-	} else {
-		png_set_gamma(png_ptr, 2.0, 0.45);
 	}
-	im = gdImageCreate(info_ptr->width, 
-		info_ptr->height);
-	if (!im) {
-		longjmp(png_ptr->jmpbuf, 1);		
-	}
-	im->interlace = info_ptr->interlace_type ? 1 : 0;
-	png_set_strip_16(png_ptr);
-	png_set_packing(png_ptr);
-	png_read_update_info(png_ptr, info_ptr);
-	/* This works because gd's internal data structure
-		happens to be compatible at this time. */
-	png_read_image(png_ptr, (png_bytepp) im->pixels);	
-	png_read_end(png_ptr, info_ptr);
-	for (i = 0; (i < info_ptr -> num_palette); i++) {
-		im->red[i] = info_ptr -> palette[i].red;
-		im->green[i] = info_ptr -> palette[i].green;
-		im->blue[i] = info_ptr -> palette[i].blue;
-		im->open[i] = 0;
-	}
-	im->colorsTotal = info_ptr -> num_palette;
-	png_destroy_read_struct(
-		&png_ptr, &info_ptr,
-		(png_infopp) 0);
-	return im;
-}
+	png_set_dither(png_ptr, std_color_cube,
+		216, 216,
+		NULL, 0);
+    }
+    png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
+    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+        int real_num_trans = 0, idx_first_trans = -1;
 
-void png_write_data(png_structp png_ptr, 
-	png_bytep data, png_size_t length)
-{
-	gdPutBuf(data, length, (gdIOCtx *)
-		png_get_io_ptr(png_ptr));	
-}
+        png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
+        for (i = 0;  i < num_trans;  ++i) {
+            if (trans[i] < 255) {
+                ++real_num_trans;
+                if (idx_first_trans < 0)
+                    idx_first_trans = i;
+            }
+        }
+        if (real_num_trans > 0) {
+            if (real_num_trans > 1 || trans[idx_first_trans] != 0) {
+                fprintf(stderr, "gd-png warning: only single-color, 100%%"
+                  " transparency supported\n");
+            } else {
+                transparent = idx_first_trans;
+            }
+        }
+    }
 
-void png_flush_data(png_structp png_ptr)
-{
-}
+    if (bit_depth < 8)
+        png_set_packing(png_ptr);   /* expand to 1 byte per pixel */
 
-static void _gdImagePng(gdImagePtr im, gdIOCtx *out)
-{
-	int x, y;
-	int depth = 1;
-	int allocated = 2;
-	int i;
-	png_structp png_ptr;
-	png_infop info_ptr;
-	png_ptr = malloc(sizeof(png_struct));
-	if (!png_ptr) {
-		return;
-	}
-	info_ptr = malloc(sizeof(png_info));
-	if (!info_ptr) {
-		return;
-	}	
-	if (setjmp(png_ptr->jmpbuf)) {
-		png_write_destroy(png_ptr);
-		free(png_ptr);
-		free(info_ptr);
-		return;
-	}
-	png_info_init(info_ptr);
-	png_write_init(png_ptr);
-	png_set_write_fn(png_ptr,
-		(void *) out,
-		png_write_data,
-		png_flush_data);	
-	while (allocated < im->colorsTotal) {
-		allocated <<= 1;
-		depth++;
-	}
-	/* Legal PNG palette bit depths are 1, 2, 4, and 8. */
-	if (depth > 2) {
-		if (depth > 4) {
-			depth = 8;
-		} else {
-			depth = 4;
-		}
-	}
-	info_ptr->width = im->sx;
-	info_ptr->height = im->sy;
-	info_ptr->bit_depth = depth;
-	info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
-	if (im->interlace) {
-		info_ptr->interlace_type = 1;
-	} else {
-		info_ptr->interlace_type = 0;
-	}
-	info_ptr->valid |= PNG_INFO_PLTE;
-	info_ptr->palette = (png_colorp) malloc(sizeof(png_color) *
-		im->colorsTotal);
-	for (i = 0; (i < im->colorsTotal); i++) {
-		info_ptr->palette[i].red = im->red[i];
-		info_ptr->palette[i].green = im->green[i];
-		info_ptr->palette[i].blue = im->blue[i];
-	}
-	info_ptr->num_palette = im->colorsTotal;
-	if (im->transparent != -1) {
-		info_ptr->trans = (png_bytep) malloc(1);
-		info_ptr->trans[0] = im->transparent;
-		info_ptr->num_trans = 1;
-	}	
-	png_write_info(png_ptr, info_ptr);
-	png_set_packing(png_ptr);
-	/* NOTE: this is dependent on the current
-		representation of pixels! It happens
-		to be compatible with libpng. */
-	png_write_image(png_ptr, (png_byte **) im->pixels);
-	png_write_end(png_ptr, info_ptr);
-	png_write_destroy(png_ptr);	
-	if (info_ptr->palette) {
-		free(info_ptr->palette);
-	}
-	if (info_ptr->trans) {
-		free(info_ptr->trans);
-	}
-	free(png_ptr);
-	free(info_ptr);
+    png_read_update_info(png_ptr, info_ptr);
+
+    /* allocate space for the PNG image data */
+    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+    if ((image_data = (png_bytep)malloc(rowbytes*height)) == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate image data\n");
+        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+        return NULL;
+    }
+    if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate row pointers\n");
+        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+        free(image_data);
+        return NULL;
+    }
+
+    /* set the individual row_pointers to point at the correct offsets */
+    for (j = 0;  j < height;  ++j)
+        row_pointers[j] = image_data + j*rowbytes;
+
+    png_read_image(png_ptr, row_pointers);   /* read whole image... */
+    png_read_end(png_ptr, NULL);             /* ...done! */
+
+    if ((im = gdImageCreate((int)width, (int)height)) == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate gdImage struct\n");
+        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+        free(image_data);
+        free(row_pointers);
+        return NULL;
+    }
+
+    im->colorsTotal = num_palette;
+    im->transparent = transparent;
+    im->interlace = (interlace_type == PNG_INTERLACE_ADAM7);
+
+    /* load the palette and mark all entries "open" (unused) for now */
+    open = im->open;
+    for (i = 0;  i < num_palette;  ++i) {
+        im->red[i]   = palette[i].red;
+        im->green[i] = palette[i].green;
+        im->blue[i]  = palette[i].blue;
+        open[i] = 1;
+    }
+    for (i = num_palette;  i < gdMaxColors;  ++i)
+        open[i] = 1;
+
+    /* can't nuke structs until done with palette */
+    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+
+    /* could copy data with memcpy(), but also want to check colormap entries */
+    for (j = 0;  j < height;  ++j) {
+        for (i = 0;  i < width;  ++i) {
+            register png_byte idx = row_pointers[j][i];
+            im->pixels[j][i] = idx;
+            open[idx] = 0;
+        }
+    }
+    /* decrement the total (used) colors if any palette entries are not used */
+    for (i = 0;  i < num_palette;  ++i) {
+        if (open[i]) {
+            --im->colorsTotal;
+        } 
+    }
+#ifdef DEBUG
+    for (i = num_palette;  i < gdMaxColors;  ++i) {
+        if (!open[i]) {
+            fprintf(stderr, "gd-png warning: image data references out-of-range"
+              " color index (%d)\n", i);
+        }
+    }
+#endif
+
+    free(image_data);
+    free(row_pointers);
+
+    return im;
 }
 
 void gdImagePng(gdImagePtr im, FILE *outFile)
 {
         gdIOCtx   *out = gdNewFileCtx(outFile);
-        _gdImagePng(im, out);
+        gdImagePngCtx(im, out);
 	out->free(out);
 }
 
-void gdImagePngCtx(gdImagePtr im, gdIOCtx *out)
-{
-        _gdImagePng(im, out);
-}
-
 void* gdImagePngPtr(gdImagePtr im, int *size)
 {
 	void	*rv;
         gdIOCtx   *out = gdNewDynamicCtx(2048, NULL);
-        _gdImagePng(im, out);
+        gdImagePngCtx(im, out);
         rv = gdDPExtractData(out, size);
 	out->free(out);
 	return rv;
 }
 
+/* This routine is based in part on code from Dale Lutz (Safe Software Inc.)
+ *  and in part on demo code from Chapter 15 of "PNG: The Definitive Guide"
+ *  (http://www.cdrom.com/pub/png/pngbook.html).
+ */
+
+void gdImagePngCtx(gdImagePtr im, gdIOCtx *outfile)
+{
+    int i, j, bit_depth, interlace_type;
+    int width = im->sx;
+    int height = im->sy;
+    int colors = im->colorsTotal;
+    int transparent = im->transparent;
+    int mapping[gdMaxColors];
+    png_byte trans_value = 0;
+    png_color palette[gdMaxColors];
+    png_structp png_ptr;
+    png_infop info_ptr;
+    volatile int remap = FALSE;
+
+
+    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+      &gdPngJmpbufStruct, gdPngErrorHandler, NULL);
+    if (png_ptr == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate libpng main struct\n");
+        return;
+    }
+
+    info_ptr = png_create_info_struct (png_ptr);
+    if (info_ptr == NULL) {
+        fprintf(stderr, "gd-png error: cannot allocate libpng info struct\n");
+        png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
+        return;
+    }
 
+    if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
+        fprintf(stderr, "gd-png error: setjmp returns error condition\n");
+        png_destroy_write_struct(&png_ptr, &info_ptr);
+        return;
+    }
+
+    png_set_write_fn(png_ptr,
+        (void *) outfile,
+        png_write_data,
+        png_flush_data);	
+
+    /* For now gd only supports palette images, for which filter type NONE is
+     * almost guaranteed to be the best.  But that's what libpng defaults to
+     * for palette images anyway, so no need to set this explicitly. */
+/*  png_set_filter(png_ptr, 0, PNG_FILTER_NONE);  */
+
+    /* may want to force maximum compression, but time penalty is large */
+/*  png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);  */
+
+    /* can set this to a smaller value without compromising compression if all
+     * image data is 16K or less; will save some decoder memory [min == 8] */
+/*  png_set_compression_window_bits(png_ptr, 15);  */
+
+    if (colors <= 2)
+        bit_depth = 1;
+    else if (colors <= 4)
+        bit_depth = 2;
+    else if (colors <= 16)
+        bit_depth = 4;
+    else
+        bit_depth = 8;
+
+    interlace_type = im->interlace? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;
+
+    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+      PNG_COLOR_TYPE_PALETTE, interlace_type,
+      PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+    if (transparent >= 0 && transparent < colors) {
+        /* always write PNG files with the transparent palette entry first to
+         * minimize size of the tRNS chunk; swap if necessary */
+        if (transparent != 0) {
+            remap = TRUE;
+            for (i = 0;  i < colors;  ++i)
+                mapping[i] = i;
+            mapping[transparent] = 0;
+            mapping[0] = transparent;
+        }
+        png_set_tRNS(png_ptr, info_ptr, &trans_value, 1, NULL);
+    }
+
+    /* convert GIF palette to libpng layout */
+    if (remap) {
+        for (i = 0;  i < colors;  ++i) {
+            palette[i].red   = im->red[mapping[i]];
+            palette[i].green = im->green[mapping[i]];
+            palette[i].blue  = im->blue[mapping[i]];
+        }
+    } else {
+        for (i = 0;  i < colors;  ++i) {
+            palette[i].red   = im->red[i];
+            palette[i].green = im->green[i];
+            palette[i].blue  = im->blue[i];
+        }
+    }
+    png_set_PLTE(png_ptr, info_ptr, palette, colors);
+
+
+    /* write out the PNG header info (everything up to first IDAT) */
+    png_write_info(png_ptr, info_ptr);
+
+    /* make sure < 8-bit images are packed into pixels as tightly as possible */
+    png_set_packing(png_ptr);
+
+    /* This code allocates a set of row buffers and copies the gd image data
+     * into them only in the case that remapping is necessary; in gd 1.3 and
+     * later, the im->pixels array is laid out identically to libpng's row
+     * pointers and can be passed to png_write_image() function directly.
+     * The remapping case could be accomplished with less memory for non-
+     * interlaced images, but interlacing causes some serious complications. */
+    if (remap) {
+        png_bytep row_pointers[height];
+
+        for (j = 0;  j < height;  ++j) {
+            if ((row_pointers[j] = (png_bytep)malloc(width)) == NULL) {
+                fprintf(stderr, "gd-png error: unable to allocate rows\n");
+                for (i = 0;  i < j;  ++i)
+                    free(row_pointers[i]);
+                return;
+            }
+            for (i = 0;  i < width;  ++i)
+                row_pointers[j][i] = mapping[im->pixels[j][i]];
+        }
+
+        png_write_image(png_ptr, row_pointers);
+        png_write_end(png_ptr, info_ptr);
+
+        for (j = 0;  j < height;  ++j)
+            free(row_pointers[j]);
+    } else {
+        png_write_image(png_ptr, im->pixels);
+        png_write_end(png_ptr, info_ptr);
+    }
+}
+
+
+static void gdPngErrorHandler (png_structp png_ptr, png_const_charp msg)
+{
+  jmpbuf_wrapper  *jmpbuf_ptr;
+
+  /* This function, aside from the extra step of retrieving the "error
+   * pointer" (below) and the fact that it exists within the application
+   * rather than within libpng, is essentially identical to libpng's
+   * default error handler.  The second point is critical:  since both
+   * setjmp() and longjmp() are called from the same code, they are
+   * guaranteed to have compatible notions of how big a jmp_buf is,
+   * regardless of whether _BSD_SOURCE or anything else has (or has not)
+   * been defined. */
+
+  fprintf(stderr, "gd-png:  fatal libpng error: %s\n", msg);
+  fflush(stderr);
+
+  jmpbuf_ptr = png_get_error_ptr(png_ptr);
+  if (jmpbuf_ptr == NULL) {         /* we are completely hosed now */
+    fprintf(stderr,
+      "gd-png:  EXTREMELY fatal error: jmpbuf unrecoverable; terminating.\n");
+    fflush(stderr);
+    exit(99);
+  }
+
+  longjmp(jmpbuf_ptr->jmpbuf, 1);
+}
 <HTML>
 <HEAD>
-<TITLE>gd 1.6</TITLE>
+<TITLE>gd 1.6.1</TITLE>
 </HEAD>
 <BODY>
-<H1>gd 1.6</H1>
+<H1>gd 1.6.1</H1>
 <H2>A graphics library for fast image creation</H2>
 <H2>Follow this link to the
 <A HREF="http://www.boutell.com/gd/">latest version
 <H3>Table of Contents</H3>
 <UL>
 <LI><A HREF="#notice">Credits and license terms</A>
+<LI><A HREF="#whatsnew1.6.1">What's new in version 1.6.1?</A>
 <LI><A HREF="#whatsnew1.6">What's new in version 1.6?</A>
 <LI><A HREF="#whatis">What is gd?</A>
 <LI><A HREF="#gdother">What if I want to use another programming language?</A>
 <p>
 Portions relating to GD2 format copyright 1999 Philip Warner.
 <p>
+Portions relating to PNG copyright 1999, Greg Roelofs.
+<p>
 <strong>Permission has been granted to copy and distribute gd in any
 context, including a commercial application, provided that this notice
 is present in user-accessible supporting documentation.</strong>
 documentation.  This software is provided "as is" without express or
 implied warranty.
 <p>
-Although their code does not appear in gd 1.6, the authors wish to 
+Although their code does not appear in gd 1.6.1, the authors wish to 
 thank David Koblas, David Rowley, and Hutchison Avenue Software 
 Corporation for their prior contributions.
 <p>
 <P>
 gd does not provide for every possible desirable graphics
 operation. It is not necessary or desirable for gd to become
-a kitchen-sink graphics package, but version 1.6 incorporates
+a kitchen-sink graphics package, but version 1.6.1 incorporates
 most of the commonly requested features for an 8-bit 2D package.
 Support for scalable fonts, and truecolor images, JPEG and 
 truecolor PNG is planned for version 2.0.
 Lincoln Stein's
 <a href="http://www-genome.wi.mit.edu/ftp/pub/software/WWW/GD.html">
 GD.pm</a> library, which uses gd as the basis for a set of
-Perl 5.x classes. Not yet updated for gd 1.6.
-be compatible.
+Perl 5.x classes. Not yet updated for gd 1.6.1.
 <h4>Any Language</h4>
 There are, at the moment, at least three simple interpreters that
 perform gd operations. You can output the desired commands to a simple
 text file from whatever scripting language you prefer to use, then
 invoke the interpreter.
 <p>
-These packages have not been updated to gd 1.6 as of this writing.
+These packages have not been updated to gd 1.6.1 as of this writing.
 <ul>
 <li><a href="http://s27w007.pswfs.gov/tgd/">tgd</a>, by Bradley K. Sherman
 <li><a href="http://www.unimelb.edu.au/fly/fly.html">fly</a>, by Martin Gleeson
 </ul>
+<P><A NAME="whatsnew1.6.1"><H3>What's new in version 1.6.1?</H3></A>
+Version 1.6.1 incorporates superior PNG reading and writing code
+from Greg Roelofs, with minor modifications by Tom Boutell. 
+Specifically, I altered his code to read non-palette images
+(converting them to palette images badly, by dithering them),
+and to tolerate palette images with types of transparency that
+gd doesn't actually support (it just ignores the advanced
+transparency features). Any bugs in this area are therefore my 
+fault, not Greg's.
+<p>
+Unlike gd 1.6, users should have no trouble linking with
+gd 1.6.1 if they follow the instructions and install all of
+the pieces. However, <strong>If you get undefined symbol errors,
+be sure to check for older versions of libpng in your
+library directories!</strong>
 <P><A NAME="whatsnew1.6"><H3>What's new in version 1.6?</H3></A>
 Version 1.6 features the following changes:
 <p>
 <A NAME="getgd"><H3>How do I get gd?</H3></A>
 <h4>By HTTP</h4>
 <ul>
-<li><a href="http://www.boutell.com/gd/http/gd1.6.tar.gz">Gzipped Tar File (Unix)</a>
-<li><a href="http://www.boutell.com/gd/http/gd16.zip">.ZIP File (Windows)</a>
+<li><a href="http://www.boutell.com/gd/http/gd1.6.1.tar.gz">Gzipped Tar File (Unix)</a>
+<li><a href="http://www.boutell.com/gd/http/gd161.zip">.ZIP File (Windows)</a>
 </ul>
 <h4>By FTP</h4>
 <ul>
-<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd1.6.tar.gz">Gzipped Tar File (Unix)</a>
-<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd16.zip">.ZIP File (Windows)</a>
+<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd1.6.1.tar.gz">Gzipped Tar File (Unix)</a>
+<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd161.zip">.ZIP File (Windows)</a>
 </ul>
 <P>
 <A NAME="buildgd"><H3>How do I build gd?</H3></A>
 consult with an experienced user of your system. Sorry, we cannot
 answer questions about basic Internet skills.
 <p>
-Unpacking the archive will produce a directory called "gd1.6".
+Unpacking the archive will produce a directory called "gd1.6.1".
 <p>
 <h4>For Unix</h4>
-<code>cd</code> to the gd1.6 directory and examine the Makefile, which
+<code>cd</code> to the gd1.6.1 directory and examine the Makefile, which
 you will probably need to change slightly depending on your operating
 system and your needs.
 <h4>For Windows, Mac, Et Cetera</h4>
 <p>
 It is not necessary to implement all functions in an I/O context if you know
 that it will only be used in limited cirsumstances. At the time of writing
-(Version 1.6, June 1999), the known requirements are:
+(Version 1.6.1, July 1999), the known requirements are:
 <p>
 <Table>
 <TR><TD>All</TD><td width=20>&nbsp;</td><TD>Must have 'free',</td></tr>
+         A MUCH BETTER MANUAL IS IN THE HYPERTEXT DOCUMENT index.html!
+         A MUCH BETTER MANUAL IS IN THE HYPERTEXT DOCUMENT index.html!
+         A MUCH BETTER MANUAL IS IN THE HYPERTEXT DOCUMENT index.html!
+         A MUCH BETTER MANUAL IS IN THE HYPERTEXT DOCUMENT index.html!
 
-   SEE index.html FOR A MUCH MORE USEFUL HYPERTEXT VERSION OF THIS DOCUMENT.
-   SEE index.html FOR A MUCH MORE USEFUL HYPERTEXT VERSION OF THIS DOCUMENT.
-   SEE index.html FOR A MUCH MORE USEFUL HYPERTEXT VERSION OF THIS DOCUMENT.
-
-
-                                    gd 1.6
+                                   gd 1.6.1
                                        
 A graphics library for fast image creation
 
-Follow this link to the [1]latest version of this document.
+Follow this link to the latest version of this document.
 
   Table of Contents
   
-     * [2]Credits and license terms
-     * [3]What's new in version 1.6?
-     * [4]What is gd?
-     * [5]What if I want to use another programming language?
-     * [6]What else do I need to use gd?
-     * [7]How do I get gd?
-     * [8]How do I build gd?
-     * [9]gd basics: using gd in your program
-     * [10]webgif: a useful example
-     * [11]Function and type reference by category
-     * [12]About the additional .gd image file format
-     * [13]Please tell us you're using gd!
-     * [14]If you have problems
-     * [15]Alphabetical quick index
+     * Credits and license terms
+     * What's new in version 1.6.1?
+     * What's new in version 1.6?
+     * What is gd?
+     * What if I want to use another programming language?
+     * What else do I need to use gd?
+     * How do I get gd?
+     * How do I build gd?
+     * gd basics: using gd in your program
+     * webgif: a useful example
+     * Function and type reference by category
+     * About the additional .gd image file format
+     * Please tell us you're using gd!
+     * If you have problems
+     * Alphabetical quick index
        
-   [16]Up to the Boutell.Com, Inc. Home Page
+   Up to the Boutell.Com, Inc. Home Page
    
   Credits and license terms
   
    In order to resolve any possible confusion regarding the authorship of
    gd, the following copyright statement covers all of the authors who
    have required such a statement. _If you are aware of any oversights in
-   this copyright notice, please contact [17]Thomas Boutell who will be
+   this copyright notice, please contact Thomas Boutell who will be
    pleased to correct them._
 
 COPYRIGHT STATEMENT FOLLOWS THIS LINE
      
      Portions relating to GD2 format copyright 1999 Philip Warner.
      
+     Portions relating to PNG copyright 1999, Greg Roelofs.
+     
      _Permission has been granted to copy and distribute gd in any
      context, including a commercial application, provided that this
      notice is present in user-accessible supporting documentation._
      notice appear in supporting documentation. This software is
      provided "as is" without express or implied warranty.
      
-     Although their code does not appear in gd 1.6, the authors wish to
-     thank David Koblas, David Rowley, and Hutchison Avenue Software
+     Although their code does not appear in gd 1.6.1, the authors wish
+     to thank David Koblas, David Rowley, and Hutchison Avenue Software
      Corporation for their prior contributions.
      
      Permission to use, copy, modify, and distribute this software and
    
    gd does not provide for every possible desirable graphics operation.
    It is not necessary or desirable for gd to become a kitchen-sink
-   graphics package, but version 1.6 incorporates most of the commonly
+   graphics package, but version 1.6.1 incorporates most of the commonly
    requested features for an 8-bit 2D package. Support for scalable
    fonts, and truecolor images, JPEG and truecolor PNG is planned for
    version 2.0.
   
     Perl
     
-   gd can also be used from Perl, courtesy of Lincoln Stein's [18]GD.pm
+   gd can also be used from Perl, courtesy of Lincoln Stein's GD.pm
    library, which uses gd as the basis for a set of Perl 5.x classes. Not
-   yet updated for gd 1.6. be compatible.
+   yet updated for gd 1.6.1.
    
     Any Language
     
    text file from whatever scripting language you prefer to use, then
    invoke the interpreter.
    
-   These packages have not been updated to gd 1.6 as of this writing.
-     * [19]tgd, by Bradley K. Sherman
-     * [20]fly, by Martin Gleeson
+   These packages have not been updated to gd 1.6.1 as of this writing.
+     * tgd, by Bradley K. Sherman
+     * fly, by Martin Gleeson
        
+  What's new in version 1.6.1?
+  
+   Version 1.6.1 incorporates superior PNG reading and writing code from
+   Greg Roelofs, with minor modifications by Tom Boutell. Specifically, I
+   altered his code to read non-palette images (converting them to
+   palette images badly, by dithering them), and to tolerate palette
+   images with types of transparency that gd doesn't actually support (it
+   just ignores the advanced transparency features). Any bugs in this
+   area are therefore my fault, not Greg's.
+   
+   Unlike gd 1.6, users should have no trouble linking with gd 1.6.1 if
+   they follow the instructions and install all of the pieces. However,
+   _If you get undefined symbol errors, be sure to check for older
+   versions of libpng in your library directories!_
+   
   What's new in version 1.6?
   
    Version 1.6 features the following changes:
           for new I/O context.
           
    _NOTE:_ In fairness to Thomas Boutell, any bug/problems with any of
-   the above features should probably be reported to [21]Philip Warner.
+   the above features should probably be reported to Philip Warner.
    
   What's new in version 1.4?
   
           
    Support for alternate data sources
           Programmers who wish to load a GIF from something other than a
-          stdio FILE * stream can use the new
-          [22]gdImageCreateFromPngSource function.
+          stdio FILE * stream can use the new gdImageCreateFromPngSource
+          function.
           
    Support for alternate data destinations
           Programmers who wish to write a GIF to something other than a
-          stdio FILE * stream can use the new [23]gdImagePngToSink
-          function.
+          stdio FILE * stream can use the new gdImagePngToSink function.
           
    More tolerant when reading GIFs
           Version 1.4 does not crash when reading certain animated GIFs,
    industry standard. Ask your ISP why it is missing._
    
    As of version 1.6, you also need the zlib compression library, and the
-   libpng library. zlib is available for a variety of platforms from
-   [24]the zlib web site. libpng is available for a variety of platforms
-   from [25]the PNG web site.
+   libpng library. zlib is available for a variety of platforms from the
+   zlib web site. libpng is available for a variety of platforms from the
+   PNG web site.
    
    You will also want a PNG viewer, if you do not already have one for
    your system, since you will need a good way to check the results of
   
     By HTTP
     
-     * [26]Gzipped Tar File (Unix)
-     * [27].ZIP File (Windows)
+     * Gzipped Tar File (Unix)
+     * .ZIP File (Windows)
        
     By FTP
     
-     * [28]Gzipped Tar File (Unix)
-     * [29].ZIP File (Windows)
+     * Gzipped Tar File (Unix)
+     * .ZIP File (Windows)
        
   How do I build gd?
   
    (Windows), please consult with an experienced user of your system.
    Sorry, we cannot answer questions about basic Internet skills.
    
-   Unpacking the archive will produce a directory called "gd1.6".
+   Unpacking the archive will produce a directory called "gd1.6.1".
    
     For Unix
     
-   cd to the gd1.6 directory and examine the Makefile, which you will
+   cd to the gd1.6.1 directory and examine the Makefile, which you will
    probably need to change slightly depending on your operating system
    and your needs.
    
 
 int main() {
         /* Declare the image */
-        [30]gdImagePtr im;
+        gdImagePtr im;
         /* Declare an output file */
         FILE *out;
         /* Declare color indexes */
         int white;
 
         /* Allocate the image: 64 pixels across by 64 pixels tall */
-        im = [31]gdImageCreate(64, 64);
+        im = gdImageCreate(64, 64);
 
         /* Allocate the color black (red, green and blue all minimum).
                 Since this is the first color in a new image, it will
                 be the background color. */
-        black = [32]gdImageColorAllocate(im, 0, 0, 0);
+        black = gdImageColorAllocate(im, 0, 0, 0);
 
         /* Allocate the color white (red, green and blue all maximum). */
-        white = [33]gdImageColorAllocate(im, 255, 255, 255);
+        white = gdImageColorAllocate(im, 255, 255, 255);
         
         /* Draw a line from the upper left to the lower right,
                 using white color index. */
-        [34]gdImageLine(im, 0, 0, 63, 63, white);
+        gdImageLine(im, 0, 0, 63, 63, white);
 
         /* Open a file for writing. "wb" means "write binary", important
                 under MSDOS, harmless under Unix. */
         out = fopen("test.png", "wb");
 
         /* Output the image to the disk file. */
-        [35]gdImagePng(im, out);
+        gdImagePng(im, out);
 
         /* Close the file. */
         fclose(out);
 
         /* Destroy the image in memory. */
-        [36]gdImageDestroy(im);
+        gdImageDestroy(im);
 }
 
    When executed, this program creates an image, allocates two colors
    The above example program should give you an idea of how the package
    works. gd provides many additional functions, which are listed in the
    following reference chapters, complete with code snippets
-   demonstrating each. There is also an [37]alphabetical index.
+   demonstrating each. There is also an alphabetical index.
    
   Webpng: a more powerful gd example
   
    
 Function and type reference
 
-     * [38]Types
-     * [39]Image creation, destruction, loading and saving
-     * [40]Drawing, styling, brushing, tiling and filling functions
-     * [41]Query functions (not color-related)
-     * [42]Font and text-handling functions
-     * [43]Color handling functions
-     * [44]Copying and resizing functions
-     * [45]Miscellaneous Functions
-     * [46]Constants
+     * Types
+     * Image creation, destruction, loading and saving
+     * Drawing, styling, brushing, tiling and filling functions
+     * Query functions (not color-related)
+     * Font and text-handling functions
+     * Color handling functions
+     * Copying and resizing functions
+     * Miscellaneous Functions
+     * Constants
        
   Types
   
    gdImage_(TYPE)_
-          The data structure in which gd stores images. [47]gdImageCreate
+          The data structure in which gd stores images. gdImageCreate
           returns a pointer to this type, and the other functions expect
           to receive a pointer to this type as their first argument. You
           may read the members sx (size on X axis), sy (size on Y axis),
 } gdImage;
 
    gdImagePtr _(TYPE)_
-          A pointer to an image structure. [48]gdImageCreate returns this
+          A pointer to an image structure. gdImageCreate returns this
           type, and the other functions expect it as the first argument.
           
    gdFont _(TYPE)_
 
    gdFontPtr _(TYPE)_
           A pointer to a font structure. Text-output functions expect
-          these as their second argument, following the [49]gdImagePtr
+          these as their second argument, following the gdImagePtr
           argument. Two such pointers are declared in the provided
           include files gdfonts.h and gdfontl.h.
           
    gdPoint _(TYPE)_
           Represents a point in the coordinate space of the image; used
-          by [50]gdImagePolygon and [51]gdImageFilledPolygon.
+          by gdImagePolygon and gdImageFilledPolygon.
           
 
 typedef struct {
 } gdPoint, *gdPointPtr;
 
    gdPointPtr _(TYPE)_
-          A pointer to a [52]gdPoint structure; passed as an argument to
-          [53]gdImagePolygon and [54]gdImageFilledPolygon.
+          A pointer to a gdPoint structure; passed as an argument to
+          gdImagePolygon and gdImageFilledPolygon.
           
    gdSource _(TYPE)_
 
 
    Represents a source from which a PNG can be read. Programmers who do
    not wish to read PNGs from a file can provide their own alternate
-   input mechanism, using the [55]gdImageCreateFromPngSource function.
-   See the documentation of that function for an example of the proper
-   use of this type.
+   input mechanism, using the gdImageCreateFromPngSource function. See
+   the documentation of that function for an example of the proper use of
+   this type.
    
    gdSink _(TYPE)_
 
 
    Represents a "sink" (destination) to which a PNG can be written.
    Programmers who do not wish to write PNGs to a file can provide their
-   own alternate output mechanism, using the [56]gdImagePngToSink
-   function. See the documentation of that function for an example of the
-   proper use of this type.
+   own alternate output mechanism, using the gdImagePngToSink function.
+   See the documentation of that function for an example of the proper
+   use of this type.
    
   Image creation, destruction, loading and saving
   
    gdImageCreate(sx, sy) _(FUNCTION)_
           gdImageCreate is called to create images. Invoke gdImageCreate
           with the x and y dimensions of the desired image. gdImageCreate
-          returns a [57]gdImagePtr to the new image, or NULL if unable to
+          returns a gdImagePtr to the new image, or NULL if unable to
           allocate the image. The image must eventually be destroyed
-          using [58]gdImageDestroy().
+          using gdImageDestroy().
           
 
 ... inside a function ...
-[59]gdImagePtr im;
+gdImagePtr im;
 im = gdImageCreate(64, 64);
 /* ... Use the image ... */
-[60]gdImageDestroy(im);
+gdImageDestroy(im);
 
    gdImageCreateFromPng(FILE *in) _(FUNCTION)_
-          gdImageCreateFromPngCtx([61]gdIOCtx *in) _(FUNCTION)_
+          gdImageCreateFromPngCtx(gdIOCtx *in) _(FUNCTION)_
           
           
           gdImageCreateFromPng is called to load images from PNG format
           files. Invoke gdImageCreateFromPng with an already opened
           pointer to a file containing the desired image.
-          gdImageCreateFromPng returns a [62]gdImagePtr to the new image,
-          or NULL if unable to load the image (most often because the
-          file is corrupt or does not contain a PNG image).
+          gdImageCreateFromPng returns a gdImagePtr to the new image, or
+          NULL if unable to load the image (most often because the file
+          is corrupt or does not contain a PNG image).
           gdImageCreateFromPng does _not_ close the file. You can inspect
           the sx and sy members of the image to determine its size. The
-          image must eventually be destroyed using [63]gdImageDestroy().
+          image must eventually be destroyed using gdImageDestroy().
           
 
-[64]gdImagePtr im;
+gdImagePtr im;
 ... inside a function ...
 FILE *in;
 in = fopen("mypng.png", "rb");
 im = gdImageCreateFromPng(in);
 fclose(in);
 /* ... Use the image ... */
-[65]gdImageDestroy(im);
+gdImageDestroy(im);
 
    gdImageCreateFromPngSource(gdSourcePtr in) _(FUNCTION)_
           gdImageCreateFromPngSource is called to load a PNG from a data
           source other than a file. Usage is very similar to the
-          [66]gdImageCreateFromPng function, except that the programmer
+          gdImageCreateFromPng function, except that the programmer
           provides a custom data source.
           
           The programmer must write an input function which accepts a
           requested, unless the end of the file has been reached, in
           which case the function should return zero, or an error has
           occurred, in which case the function should return -1. The
-          programmer then creates a [67]gdSource structure and sets the
+          programmer then creates a gdSource structure and sets the
           source pointer to the input function and the context pointer to
           any value which is useful to the programmer.
           
-          The example below implements [68]gdImageCreateFromPng by
-          creating a custom data source and invoking
-          gdImageCreateFromPngSource.
+          The example below implements gdImageCreateFromPng by creating a
+          custom data source and invoking gdImageCreateFromPngSource.
           
 
 static int freadWrapper(void *context, char *buf, int len);
 }
 
    gdImageCreateFromGd(FILE *in) _(FUNCTION)_
-          gdImageCreateFromGdCtx([69]gdIOCtx *in) _(FUNCTION)_
+          gdImageCreateFromGdCtx(gdIOCtx *in) _(FUNCTION)_
           
           
           gdImageCreateFromGd is called to load images from gd format
           files. Invoke gdImageCreateFromGd with an already opened
-          pointer to a file containing the desired image in the [70]gd
-          file format, which is specific to gd and intended for very fast
+          pointer to a file containing the desired image in the gd file
+          format, which is specific to gd and intended for very fast
           loading. (It is _not_ intended for compression; for
-          compression, use PNG.) gdImageCreateFromGd returns a
-          [71]gdImagePtr to the new image, or NULL if unable to load the
-          image (most often because the file is corrupt or does not
-          contain a gd format image). gdImageCreateFromGd does _not_
-          close the file. You can inspect the sx and sy members of the
-          image to determine its size. The image must eventually be
-          destroyed using [72]gdImageDestroy().
+          compression, use PNG.) gdImageCreateFromGd returns a gdImagePtr
+          to the new image, or NULL if unable to load the image (most
+          often because the file is corrupt or does not contain a gd
+          format image). gdImageCreateFromGd does _not_ close the file.
+          You can inspect the sx and sy members of the image to determine
+          its size. The image must eventually be destroyed using
+          gdImageDestroy().
           
 
 ... inside a function ...
-[73]gdImagePtr im;
+gdImagePtr im;
 FILE *in;
 in = fopen("mygd.gd", "rb");
 im = gdImageCreateFromGd(in);
 fclose(in);
 /* ... Use the image ... */
-[74]gdImageDestroy(im);
+gdImageDestroy(im);
 
    gdImageCreateFromGd2(FILE *in) _(FUNCTION)_
-          gdImageCreateFromGd2Ctx([75]gdIOCtx *in) _(FUNCTION)_
+          gdImageCreateFromGd2Ctx(gdIOCtx *in) _(FUNCTION)_
           
           
           gdImageCreateFromGd2 is called to load images from gd2 format
           files. Invoke gdImageCreateFromGd2 with an already opened
-          pointer to a file containing the desired image in the [76]gd2
-          file format, which is specific to gd2 and intended for fast
-          loading of parts of large images. (It is a compressed format,
-          but generally not as good a LZW compression).
-          gdImageCreateFromGd returns a [77]gdImagePtr to the new image,
-          or NULL if unable to load the image (most often because the
-          file is corrupt or does not contain a gd format image).
-          gdImageCreateFromGd2 does _not_ close the file. You can inspect
-          the sx and sy members of the image to determine its size. The
-          image must eventually be destroyed using [78]gdImageDestroy().
+          pointer to a file containing the desired image in the gd2 file
+          format, which is specific to gd2 and intended for fast loading
+          of parts of large images. (It is a compressed format, but
+          generally not as good a LZW compression). gdImageCreateFromGd
+          returns a gdImagePtr to the new image, or NULL if unable to
+          load the image (most often because the file is corrupt or does
+          not contain a gd format image). gdImageCreateFromGd2 does _not_
+          close the file. You can inspect the sx and sy members of the
+          image to determine its size. The image must eventually be
+          destroyed using gdImageDestroy().
           
 
 ... inside a function ...
-[79]gdImagePtr im;
+gdImagePtr im;
 FILE *in;
 in = fopen("mygd.gd2", "rb");
 im = gdImageCreateFromGd2(in);
 fclose(in);
 /* ... Use the image ... */
-[80]gdImageDestroy(im);
+gdImageDestroy(im);
 
    gdImageCreateFromGd2Part(FILE *in, int srcX, int srcY, int w, int h)
           _(FUNCTION)_
-          gdImageCreateFromGd2PartCtx([81]gdIOCtx *in) _(FUNCTION)_
+          gdImageCreateFromGd2PartCtx(gdIOCtx *in) _(FUNCTION)_
           
           
           gdImageCreateFromGd2Part is called to load parts of images from
-          [82]gd2 format files. Invoked in the same way as
-          [83]gdImageCreateFromGd2, but with extra parameters indicating
-          the source (x, y) and width/height of the desired image.
-          gdImageCreateFromGd2Part returns a [84]gdImagePtr to the new
-          image, or NULL if unable to load the image. The image must
-          eventually be destroyed using [85]gdImageDestroy().
+          gd2 format files. Invoked in the same way as
+          gdImageCreateFromGd2, but with extra parameters indicating the
+          source (x, y) and width/height of the desired image.
+          gdImageCreateFromGd2Part returns a gdImagePtr to the new image,
+          or NULL if unable to load the image. The image must eventually
+          be destroyed using gdImageDestroy().
           
    gdImageCreateFromXbm(FILE *in) _(FUNCTION)_
           gdImageCreateFromXbm is called to load images from X bitmap
           format files. Invoke gdImageCreateFromXbm with an already
           opened pointer to a file containing the desired image.
-          gdImageCreateFromXbm returns a [86]gdImagePtr to the new image,
-          or NULL if unable to load the image (most often because the
-          file is corrupt or does not contain an X bitmap format image).
+          gdImageCreateFromXbm returns a gdImagePtr to the new image, or
+          NULL if unable to load the image (most often because the file
+          is corrupt or does not contain an X bitmap format image).
           gdImageCreateFromXbm does _not_ close the file. You can inspect
           the sx and sy members of the image to determine its size. The
-          image must eventually be destroyed using [87]gdImageDestroy().
+          image must eventually be destroyed using gdImageDestroy().
           
 
 ... inside a function ...
-[88]gdImagePtr im;
+gdImagePtr im;
 FILE *in;
 in = fopen("myxbm.xbm", "rb");
 im = gdImageCreateFromXbm(in);
 fclose(in);
 /* ... Use the image ... */
-[89]gdImageDestroy(im);
+gdImageDestroy(im);
 
    gdImageDestroy(gdImagePtr im) _(FUNCTION)_
           gdImageDestroy is used to free the memory associated with an
           image. It is important to invoke gdImageDestroy before exiting
-          your program or assigning a new image to a [90]gdImagePtr
-          variable.
+          your program or assigning a new image to a gdImagePtr variable.
           
 
 ... inside a function ...
-[91]gdImagePtr im;
-im = [92]gdImageCreate(10, 10);
+gdImagePtr im;
+im = gdImageCreate(10, 10);
 /* ... Use the image ... */
 /* Now destroy it */
-[93]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImagePng(gdImagePtr im, FILE *out) _(FUNCTION)_
           gdImagePng outputs the specified image to the specified file in
           
 
 ... inside a function ...
-[94]gdImagePtr im;
+gdImagePtr im;
 int black, white;
 FILE *out;
 /* Create the image */
-im = [95]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Allocate background */
-white = [96]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate drawing color */
-black = [97]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Draw rectangle */
-[98]gdImageRectangle(im, 0, 0, 99, 99, black);
+gdImageRectangle(im, 0, 0, 99, 99, black);
 /* Open output file in binary mode */
 out = fopen("rect.png", "wb");
 /* Write PNG */
 /* Close file */
 fclose(out);
 /* Destroy image */
-[99]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void* gdImagePngPtr(gdImagePtr im, int *size) _(FUNCTION)_
           Identical to gdImagePng except that it returns a pointer to a
    gdImagePngToSink(gdImagePtr im, gdSinkPtr out) _(FUNCTION)_
           gdImagePngToSink is called to write a PNG to a data "sink"
           (destination) other than a file. Usage is very similar to the
-          [100]gdImagePng function, except that the programmer provides a
+          gdImagePng function, except that the programmer provides a
           custom data sink.
           
           The programmer must write an output function which accepts a
           as arguments. This function must write the number of bytes
           requested and return that number, unless an error has occurred,
           in which case the function should return -1. The programmer
-          then creates a [101]gdSink structure and sets the sink pointer
-          to the output function and the context pointer to any value
-          which is useful to the programmer.
+          then creates a gdSink structure and sets the sink pointer to
+          the output function and the context pointer to any value which
+          is useful to the programmer.
           
-          The example below implements [102]gdImagePng by creating a
-          custom data source and invoking gdImagePngFromSink.
+          The example below implements gdImagePng by creating a custom
+          data source and invoking gdImagePngFromSink.
           
 
 static int stdioSink(void *context, char *buffer, int len)
 
    void gdImageGd(gdImagePtr im, FILE *out) _(FUNCTION)_
           gdImageGd outputs the specified image to the specified file in
-          the [103]gd image format. The file must be open for writing.
-          Under MSDOS and all versions of Windows, it is important to use
-          "wb" as opposed to simply "w" as the mode when opening the
-          file, and under Unix there is no penalty for doing so.
-          gdImagePng does _not_ close the file; your code must do so.
+          the gd image format. The file must be open for writing. Under
+          MSDOS and all versions of Windows, it is important to use "wb"
+          as opposed to simply "w" as the mode when opening the file, and
+          under Unix there is no penalty for doing so. gdImagePng does
+          _not_ close the file; your code must do so.
           
           The gd image format is intended for fast reads and writes of
           images your program will need frequently to build other images.
           
 
 ... inside a function ...
-[104]gdImagePtr im;
+gdImagePtr im;
 int black, white;
 FILE *out;
 /* Create the image */
-im = [105]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Allocate background */
-white = [106]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate drawing color */
-black = [107]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Draw rectangle */
-[108]gdImageRectangle(im, 0, 0, 99, 99, black);
+gdImageRectangle(im, 0, 0, 99, 99, black);
 /* Open output file in binary mode */
 out = fopen("rect.gd", "wb");
 /* Write gd format file */
 /* Close file */
 fclose(out);
 /* Destroy image */
-[109]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void* gdImageGdPtr(gdImagePtr im, int *size) _(FUNCTION)_
           Identical to gdImageGd except that it returns a pointer to a
    void gdImageGd2(gdImagePtr im, FILE *out, int chunkSize, int fmt)
           _(FUNCTION)_
           gdImageGd2 outputs the specified image to the specified file in
-          the [110]gd2 image format. The file must be open for writing.
-          Under MSDOS and all versions of Windows, it is important to use
-          "wb" as opposed to simply "w" as the mode when opening the
-          file, and under Unix there is no penalty for doing so.
-          gdImageGd2 does _not_ close the file; your code must do so.
+          the gd2 image format. The file must be open for writing. Under
+          MSDOS and all versions of Windows, it is important to use "wb"
+          as opposed to simply "w" as the mode when opening the file, and
+          under Unix there is no penalty for doing so. gdImageGd2 does
+          _not_ close the file; your code must do so.
           
           The gd2 image format is intended for fast reads and writes of
           parts of images. It is a compressed format, and well suited to
           
 
 ... inside a function ...
-[111]gdImagePtr im;
+gdImagePtr im;
 int black, white;
 FILE *out;
 /* Create the image */
-im = [112]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Allocate background */
-white = [113]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate drawing color */
-black = [114]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Draw rectangle */
-[115]gdImageRectangle(im, 0, 0, 99, 99, black);
+gdImageRectangle(im, 0, 0, 99, 99, black);
 /* Open output file in binary mode */
 out = fopen("rect.gd", "wb");
 /* Write gd2 format file */
 /* Close file */
 fclose(out);
 /* Destroy image */
-[116]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void* gdImageGd2Ptr(gdImagePtr im, int chunkSize, int fmt, int *size)
           _(FUNCTION)_
           _(FUNCTION)_
           gdImageSetPixel sets a pixel to a particular color index.
           Always use this function or one of the other drawing functions
-          to access pixels; do not access the pixels of the [117]gdImage
+          to access pixels; do not access the pixels of the gdImage
           structure directly.
           
 
 ... inside a function ...
-[118]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [119]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [120]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [121]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Set a pixel near the center. */
 gdImageSetPixel(im, 50, 50, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[122]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageLine(gdImagePtr im, int x1, int y1, int x2, int y2, int
           color) _(FUNCTION)_
           gdImageLine is used to draw a line between two endpoints (x1,y1
           and x2, y2). The line is drawn using the color index specified.
           Note that the color index can be an actual color returned by
-          [123]gdImageColorAllocate or one of [124]gdStyled,
-          [125]gdBrushed or [126]gdStyledBrushed.
+          gdImageColorAllocate or one of gdStyled, gdBrushed or
+          gdStyledBrushed.
           
 
 ... inside a function ...
-[127]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [128]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [129]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [130]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a line from the upper left corner to the lower right corner. */
 gdImageLine(im, 0, 0, 99, 99, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[131]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageDashedLine(gdImagePtr im, int x1, int y1, int x2, int y2,
           int color) _(FUNCTION)_
           gdImageDashedLine is provided _solely for backwards
           compatibility _with gd 1.0. New programs should draw dashed
-          lines using the normal [132]gdImageLine function and the new
-          [133]gdImageSetStyle function.
+          lines using the normal gdImageLine function and the new
+          gdImageSetStyle function.
           
           gdImageDashedLine is used to draw a dashed line between two
           endpoints (x1,y1 and x2, y2). The line is drawn using the color
           
 
 ... inside a function ...
-[134]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [135]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [136]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [137]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a dashed line from the upper left corner to the lower right corner. */
 gdImageDashedLine(im, 0, 0, 99, 99);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[138]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImagePolygon(gdImagePtr im, gdPointPtr points, int pointsTotal,
           int color) _(FUNCTION)_
           gdImagePolygon is used to draw a polygon with the verticies (at
           least 3) specified, using the color index specified. See also
-          [139]gdImageFilledPolygon.
+          gdImageFilledPolygon.
           
 
 ... inside a function ...
-[140]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
 /* Points of polygon */
-[141]gdPoint points[3];
-im = [142]gdImageCreate(100, 100);
+gdPoint points[3];
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [143]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [144]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a triangle. */
 points[0].x = 50;
 points[0].y = 0;
 gdImagePolygon(im, points, 3, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[145]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageRectangle(gdImagePtr im, int x1, int y1, int x2, int y2,
           int color) _(FUNCTION)_
           
 
 ... inside a function ...
-[146]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [147]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [148]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [149]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a rectangle occupying the central area. */
 gdImageRectangle(im, 25, 25, 74, 74, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[150]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageFilledPolygon(gdImagePtr im, gdPointPtr points, int
           pointsTotal, int color) _(FUNCTION)_
           gdImageFilledPolygon is used to fill a polygon with the
           verticies (at least 3) specified, using the color index
-          specified. See also [151]gdImagePolygon.
+          specified. See also gdImagePolygon.
           
 
 ... inside a function ...
-[152]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
 int red;
 /* Points of polygon */
-[153]gdPoint points[3];
-im = [154]gdImageCreate(100, 100);
+gdPoint points[3];
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [155]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [156]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate the color red. */
-red = [157]gdImageColorAllocate(im, 255, 0, 0);
+red = gdImageColorAllocate(im, 255, 0, 0);
 /* Draw a triangle. */
 points[0].x = 50;
 points[0].y = 0;
 /* Paint it in white */
 gdImageFilledPolygon(im, points, 3, white);
 /* Outline it in red; must be done second */
-[158]gdImagePolygon(im, points, 3, red);
+gdImagePolygon(im, points, 3, red);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[159]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageFilledRectangle(gdImagePtr im, int x1, int y1, int x2, int
           y2, int color) _(FUNCTION)_
           
 
 ... inside a function ...
-[160]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [161]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [162]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [163]int gdImageColorAllocate(im, 255, 255, 255);
+white = int gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a filled rectangle occupying the central area. */
 gdImageFilledRectangle(im, 25, 25, 74, 74, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[164]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s,
           int e, int color) _(FUNCTION)_
           
 
 ... inside a function ...
-[165]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [166]gdImageCreate(100, 50);
+im = gdImageCreate(100, 50);
 /* Background color (first allocated) */
-black = [167]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [168]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Inscribe an ellipse in the image. */
 gdImageArc(im, 50, 25, 98, 48, 0, 360, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[169]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int
           color) _(FUNCTION)_
           gdImageFillToBorder floods a portion of the image with the
           specified color, beginning at the specified point and stopping
           at the specified border color. For a way of flooding an area
-          defined by the color of the starting point, see
-          [170]gdImageFill.
+          defined by the color of the starting point, see gdImageFill.
           
-          The border color _cannot_ be a special color such as
-          [171]gdTiled; it must be a proper solid color. The fill color
-          can be, however.
+          The border color _cannot_ be a special color such as gdTiled;
+          it must be a proper solid color. The fill color can be,
+          however.
           
           Note that gdImageFillToBorder is recursive. It is not the most
           naive implementation possible, and the implementation is
           
 
 ... inside a function ...
-[172]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
 int red;
-im = [173]gdImageCreate(100, 50);
+im = gdImageCreate(100, 50);
 /* Background color (first allocated) */
-black = [174]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [175]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate the color red. */
-red = [176]gdImageColorAllocate(im, 255, 0, 0);
+red = gdImageColorAllocate(im, 255, 0, 0);
 /* Inscribe an ellipse in the image. */
 gdImageArc(im, 50, 25, 98, 48, 0, 360, white);
 /* Flood-fill the ellipse. Fill color is red, border color is
 gdImageFillToBorder(im, 50, 50, white, red);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[177]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageFill(gdImagePtr im, int x, int y, int color) _(FUNCTION)_
           gdImageFill floods a portion of the image with the specified
           color, beginning at the specified point and flooding the
           surrounding region of the same color as the starting point. For
           a way of flooding a region defined by a specific border color
-          rather than by its interior color, see
-          [178]gdImageFillToBorder.
+          rather than by its interior color, see gdImageFillToBorder.
           
-          The fill color can be [179]gdTiled, resulting in a tile fill
-          using another image as the tile. However, the tile image cannot
-          be transparent. If the image you wish to fill with has a
-          transparent color index, call [180]gdImageTransparent on the
-          tile image and set the transparent color index to -1 to turn
-          off its transparency.
+          The fill color can be gdTiled, resulting in a tile fill using
+          another image as the tile. However, the tile image cannot be
+          transparent. If the image you wish to fill with has a
+          transparent color index, call gdImageTransparent on the tile
+          image and set the transparent color index to -1 to turn off its
+          transparency.
           
           Note that gdImageFill is recursive. It is not the most naive
           implementation possible, and the implementation is expected to
           
 
 ... inside a function ...
-[181]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
 int red;
-im = [182]gdImageCreate(100, 50);
+im = gdImageCreate(100, 50);
 /* Background color (first allocated) */
-black = [183]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [184]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Allocate the color red. */
-red = [185]gdImageColorAllocate(im, 255, 0, 0);
+red = gdImageColorAllocate(im, 255, 0, 0);
 /* Inscribe an ellipse in the image. */
 gdImageArc(im, 50, 25, 98, 48, 0, 360, white);
 /* Flood-fill the ellipse. Fill color is red, and will replace the
 gdImageFill(im, 50, 50, red);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[186]gdImageDestroy(im);
+gdImageDestroy(im);
 
    void gdImageSetBrush(gdImagePtr im, gdImagePtr brush) _(FUNCTION)_
           A "brush" is an image used to draw wide, shaped strokes in
           another image. Just as a paintbrush is not a single point, a
           brush image need not be a single pixel. _Any_ gd image can be
           used as a brush, and by setting the transparent color index of
-          the brush image with [187]gdImageColorTransparent, a brush of
-          any shape can be created. All line-drawing functions, such as
-          [188]gdImageLine and [189]gdImagePolygon, will use the current
-          brush if the special "color" [190]gdBrushed or
-          [191]gdStyledBrushed is used when calling them.
+          the brush image with gdImageColorTransparent, a brush of any
+          shape can be created. All line-drawing functions, such as
+          gdImageLine and gdImagePolygon, will use the current brush if
+          the special "color" gdBrushed or gdStyledBrushed is used when
+          calling them.
           
           gdImageSetBrush is used to specify the brush to be used in a
           particular image. You can set any image to be the brush. If the
           You need not take any special action when you are finished with
           a brush. As for any other image, if you will not be using the
           brush image for any further purpose, you should call
-          [192]gdImageDestroy. You must not use the color [193]gdBrushed
-          if the current brush has been destroyed; you can of course set
-          a new brush to replace it.
+          gdImageDestroy. You must not use the color gdBrushed if the
+          current brush has been destroyed; you can of course set a new
+          brush to replace it.
           
 
 ... inside a function ...
-[194]gdImagePtr im, brush;
+gdImagePtr im, brush;
 FILE *in;
 int black;
-im = [195]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Open the brush PNG. For best results, portions of the
         brush that should be transparent (ie, not part of the
         brush shape) should have the transparent color index. */
 in = fopen("star.png", "rb");
-brush = [196]gdImageCreateFromPng(in);
+brush = gdImageCreateFromPng(in);
 /* Background color (first allocated) */
-black = [197]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 gdImageSetBrush(im, brush);
 /* Draw a line from the upper left corner to the lower right corner
         using the brush. */
-[198]gdImageLine(im, 0, 0, 99, 99, [199]gdBrushed);
+gdImageLine(im, 0, 0, 99, 99, gdBrushed);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[200]gdImageDestroy(im);
+gdImageDestroy(im);
 /* Destroy the brush image */
-[201]gdImageDestroy(brush);
+gdImageDestroy(brush);
 
    void gdImageSetTile(gdImagePtr im, gdImagePtr tile) _(FUNCTION)_
           A "tile" is an image used to fill an area with a repeated
           pattern. _Any_ gd image can be used as a tile, and by setting
           the transparent color index of the tile image with
-          [202]gdImageColorTransparent, a tile that allows certain parts
-          of the underlying area to shine through can be created. All
-          region-filling functions, such as [203]gdImageFill and
-          [204]gdImageFilledPolygon, will use the current tile if the
-          special "color" [205]gdTiled is used when calling them.
+          gdImageColorTransparent, a tile that allows certain parts of
+          the underlying area to shine through can be created. All
+          region-filling functions, such as gdImageFill and
+          gdImageFilledPolygon, will use the current tile if the special
+          "color" gdTiled is used when calling them.
           
           gdImageSetTile is used to specify the tile to be used in a
           particular image. You can set any image to be the tile. If the
           You need not take any special action when you are finished with
           a tile. As for any other image, if you will not be using the
           tile image for any further purpose, you should call
-          [206]gdImageDestroy. You must not use the color [207]gdTiled if
-          the current tile has been destroyed; you can of course set a
-          new tile to replace it.
+          gdImageDestroy. You must not use the color gdTiled if the
+          current tile has been destroyed; you can of course set a new
+          tile to replace it.
           
 
 ... inside a function ...
-[208]gdImagePtr im, tile;
+gdImagePtr im, tile;
 FILE *in;
 int black;
-im = [209]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Open the tile PNG. For best results, portions of the
         tile that should be transparent (ie, allowing the
         background to shine through) should have the transparent
         color index. */
 in = fopen("star.png", "rb");
-tile = [210]gdImageCreateFromPng(in);
+tile = gdImageCreateFromPng(in);
 /* Background color (first allocated) */
-black = [211]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 gdImageSetTile(im, tile);
 /* Fill an area using the tile. */
-[212]gdImageFilledRectangle(im, 25, 25, 75, 75, [213]gdTiled);
+gdImageFilledRectangle(im, 25, 25, 75, 75, gdTiled);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[214]gdImageDestroy(im);
+gdImageDestroy(im);
 /* Destroy the tile image */
-[215]gdImageDestroy(tile);
+gdImageDestroy(tile);
 
    void gdImageSetStyle(gdImagePtr im, int *style, int styleLength)
           _(FUNCTION)_
           
           To use gdImageSetStyle, create an array of integers and assign
           them the desired series of color values to be repeated. You can
-          assign the special color value [216]gdTransparent to indicate
-          that the existing color should be left unchanged for that
-          particular pixel (allowing a dashed line to be attractively
-          drawn over an existing image).
+          assign the special color value gdTransparent to indicate that
+          the existing color should be left unchanged for that particular
+          pixel (allowing a dashed line to be attractively drawn over an
+          existing image).
           
           Then, to draw a line using the style, use the normal
-          [217]gdImageLine function with the special color value
-          [218]gdStyled.
+          gdImageLine function with the special color value gdStyled.
           
-          As of [219]version 1.1.1, the style array is copied when you
-          set the style, so you need not be concerned with keeping the
-          array around indefinitely. This should not break existing code
-          that assumes styles are not copied.
+          As of version 1.1.1, the style array is copied when you set the
+          style, so you need not be concerned with keeping the array
+          around indefinitely. This should not break existing code that
+          assumes styles are not copied.
           
           You can also combine styles and brushes to draw the brush image
           at intervals instead of in a continuous stroke. When creating a
           differently: zero (0) indicates pixels at which the brush
           should not be drawn, while one (1) indicates pixels at which
           the brush should be drawn. To draw a styled, brushed line, you
-          must use the special color value [220]gdStyledBrushed. For an
+          must use the special color value gdStyledBrushed. For an
           example of this feature in use, see gddemo.c (provided in the
           distribution).
           
 
-[221]gdImagePtr im;
+gdImagePtr im;
 int styleDotted[2], styleDashed[6];
 FILE *in;
 int black;
 int red;
-im = [222]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [223]gdImageColorAllocate(im, 0, 0, 0);
-red = [224]gdImageColorAllocate(im, 255, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
+red = gdImageColorAllocate(im, 255, 0, 0);
 /* Set up dotted style. Leave every other pixel alone. */
 styleDotted[0] = red;
 styleDotted[1] = gdTransparent;
         in the style! */
 gdImageSetStyle(im, styleDotted, 2);
 /* Draw a line from the upper left corner to the lower right corner. */
-[225]gdImageLine(im, 0, 0, 99, 99, [226]gdStyled);
+gdImageLine(im, 0, 0, 99, 99, gdStyled);
 /* Now the dashed line. */
 gdImageSetStyle(im, styleDashed, 6);
-[227]gdImageLine(im, 0, 99, 0, 99, [228]gdStyled);
+gdImageLine(im, 0, 99, 0, 99, gdStyled);
 
 /* ... Do something with the image, such as saving it to a file ... */
 
 /* Destroy it */
-[229]gdImageDestroy(im);
+gdImageDestroy(im);
 
   Query Functions
   
         int gdImageGetPixel(gdImagePtr im, int x, int y) _(FUNCTION)_
                 gdImageGetPixel() retrieves the color index of a
                 particular pixel. Always use this function to query
-                pixels; do not access the pixels of the [230]gdImage
-                structure directly.
+                pixels; do not access the pixels of the gdImage structure
+                directly.
                 
 
 ... inside a function ...
 gdImagePtr im;
 int c;
 in = fopen("mypng.png", "rb");
-im = [231]gdImageCreateFromPng(in);
+im = gdImageCreateFromPng(in);
 fclose(in);
 c = gdImageGetPixel(im, gdImageSX(im) / 2, gdImageSY(im) / 2);
 printf("The value of the center pixel is %d; RGB values are %d,%d,%d\n",
         c, im->red[c], im->green[c], im->blue[c]);
-[232]gdImageDestroy(im);
+gdImageDestroy(im);
 
         int gdImageBoundsSafe(gdImagePtr im, int x, int y) _(FUNCTION)_
                 gdImageBoundsSafe returns true (1) if the specified point
                 
 
 ... inside a function ...
-[233]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [234]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 if (gdImageBoundsSafe(im, 50, 50)) {
         printf("50, 50 is within the image bounds\n");
 } else {
         printf("50, 50 is outside the image bounds\n");
 }
-[235]gdImageDestroy(im);
+gdImageDestroy(im);
 
         int gdImageGreen(gdImagePtr im, int color) _(MACRO)_
                 gdImageGreen is a macro which returns the green component
         void gdImageChar(gdImagePtr im, gdFontPtr font, int x, int y, int
                 c, int color) _(FUNCTION)_
                 gdImageChar is used to draw single characters on the
-                image. (To draw multiple characters, use
-                [236]gdImageString or [237]gdImageString16.) The second
-                argument is a pointer to a font definition structure;
-                five fonts are provided with gd, gdFontTiny, gdFontSmall,
-                gdFontMediumBold, gdFontLarge, and gdFontGiant. You must
-                include the files "gdfontt.h", "gdfonts.h", "gdfontmb.h",
-                "gdfontl.h" and "gdfontg.h" respectively and (if you are
-                not using a library-based approach) link with the
-                corresponding .c files to use the provided fonts. The
-                character specified by the fifth argument is drawn from
-                left to right in the specified color. (See
-                [238]gdImageCharUp for a way of drawing vertical text.)
-                Pixels not set by a particular character retain their
-                previous color.
+                image. (To draw multiple characters, use gdImageString or
+                gdImageString16.) The second argument is a pointer to a
+                font definition structure; five fonts are provided with
+                gd, gdFontTiny, gdFontSmall, gdFontMediumBold,
+                gdFontLarge, and gdFontGiant. You must include the files
+                "gdfontt.h", "gdfonts.h", "gdfontmb.h", "gdfontl.h" and
+                "gdfontg.h" respectively and (if you are not using a
+                library-based approach) link with the corresponding .c
+                files to use the provided fonts. The character specified
+                by the fifth argument is drawn from left to right in the
+                specified color. (See gdImageCharUp for a way of drawing
+                vertical text.) Pixels not set by a particular character
+                retain their previous color.
                 
 
 #include "gd.h"
 #include "gdfontl.h"
 ... inside a function ...
-[239]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [240]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [241]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [242]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a character. */
 gdImageChar(im, gdFontLarge, 0, 0, 'Q', white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[243]gdImageDestroy(im);
+gdImageDestroy(im);
 
         void gdImageCharUp(gdImagePtr im, gdFontPtr font, int x, int y,
                 int c, int color) _(FUNCTION)_
                 gdImageCharUp is used to draw single characters on the
                 image, rotated 90 degrees. (To draw multiple characters,
-                use [244]gdImageStringUp or [245]gdImageStringUp16.) The
-                second argument is a pointer to a font definition
-                structure; five fonts are provided with gd, gdFontTiny,
-                gdFontSmall, gdFontMediumBold, gdFontLarge, and
-                gdFontGiant. You must include the files "gdfontt.h",
-                "gdfonts.h", "gdfontmb.h", "gdfontl.h" and "gdfontg.h"
-                respectively and (if you are not using a library-based
-                approach) link with the corresponding .c files to use the
-                provided fonts. The character specified by the fifth
-                argument is drawn from bottom to top, rotated at a
-                90-degree angle, in the specified color. (See
-                [246]gdImageChar for a way of drawing horizontal text.)
-                Pixels not set by a particular character retain their
-                previous color.
+                use gdImageStringUp or gdImageStringUp16.) The second
+                argument is a pointer to a font definition structure;
+                five fonts are provided with gd, gdFontTiny, gdFontSmall,
+                gdFontMediumBold, gdFontLarge, and gdFontGiant. You must
+                include the files "gdfontt.h", "gdfonts.h", "gdfontmb.h",
+                "gdfontl.h" and "gdfontg.h" respectively and (if you are
+                not using a library-based approach) link with the
+                corresponding .c files to use the provided fonts. The
+                character specified by the fifth argument is drawn from
+                bottom to top, rotated at a 90-degree angle, in the
+                specified color. (See gdImageChar for a way of drawing
+                horizontal text.) Pixels not set by a particular
+                character retain their previous color.
                 
 
 #include "gd.h"
 #include "gdfontl.h"
 ... inside a function ...
-[247]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
-im = [248]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [249]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [250]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a character upwards so it rests against the top of the image. */
 gdImageCharUp(im, gdFontLarge,
         0, gdFontLarge->h, 'Q', white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[251]gdImageDestroy(im);
+gdImageDestroy(im);
 
         void gdImageString(gdImagePtr im, gdFontPtr font, int x, int y,
                 unsigned char *s, int color) _(FUNCTION)_
                 gdImageString is used to draw multiple characters on the
-                image. (To draw single characters, use [252]gdImageChar.)
-                The second argument is a pointer to a font definition
+                image. (To draw single characters, use gdImageChar.) The
+                second argument is a pointer to a font definition
                 structure; five fonts are provided with gd, gdFontTiny,
                 gdFontSmall, gdFontMediumBold, gdFontLarge, and
                 gdFontGiant. You must include the files "gdfontt.h",
                 approach) link with the corresponding .c files to use the
                 provided fonts. The null-terminated C string specified by
                 the fifth argument is drawn from left to right in the
-                specified color. (See [253]gdImageStringUp for a way of
+                specified color. (See gdImageStringUp for a way of
                 drawing vertical text.) Pixels not set by a particular
                 character retain their previous color.
                 
 #include "gdfontl.h"
 #include <string.h>
 ... inside a function ...
-[254]gdImagePtr im;
+gdImagePtr im;
 int black;
 int white;
 /* String to draw. */
 char *s = "Hello.";
-im = [255]gdImageCreate(100, 100);
+im = gdImageCreate(100, 100);
 /* Background color (first allocated) */
-black = [256]gdImageColorAllocate(im, 0, 0, 0);
+black = gdImageColorAllocate(im, 0, 0, 0);
 /* Allocate the color white (red, green and blue all maximum). */
-white = [257]gdImageColorAllocate(im, 255, 255, 255);
+white = gdImageColorAllocate(im, 255, 255, 255);
 /* Draw a centered string. */
 gdImageString(im, gdFontLarge,
         im->w / 2 - (strlen(s) * gdFontLarge->w / 2),
         s, white);
 /* ... Do something with the image, such as saving it to a file... */
 /* Destroy it */
-[258]gdImageDestroy(im);
+gdImageDestroy(im);
 
         void gdImageString16(gdImagePtr im, gdFontPtr font, int x, int y,
                 unsigned short *s, int color) _(FUNCTION)_
                 gdImageString is used to draw multiple 16-bit characters
                 on the image. (To draw single characters, use
-                [259]gdImageChar.) The second argument is a pointer to a
-                font definition structure; five fonts are provided with
-                gd, gdFontTiny, gdFontSmall, gdFontMediumBold,
-                gdFontLarge, and gdFontGiant. You must include the files
-                "gdfontt.h", "gdfonts.h", "gdfontmb.h", "gdfontl.h" and
-                "gdfontg.h" respectively and (if you are not using a
-                library-based approach) link with the corresponding .c
-                files to use the provided fonts. The null-terminated
-                string of characters represented as 16-bit unsigned short
-                integers specified by the fifth argument is drawn from
-                left to right in the specified color. (See
-                [260]gdImageStringUp16 for a way of drawing vertical
-                text.) Pixels not set by a particular character retain
-                their previous color.
+                gdImageChar.) The second argument is a pointer to a font
+                definition structure; five fonts are provided with gd,
+                gdFontTiny, gdFontSmall, gdFontMediumBold, gdFontLarge,
+                and gdFontGiant. You must include the files "gdfontt.h",
+                "gdfonts.h", "gdfontmb.h", "gdfontl.h" and "gdfontg.h"
+                respectively and (if you are not using a library-based
+                approach) link with the corresponding .c files to use the
+                provided fonts. The null-terminated string of characters
+                represented as 16-bit unsigned short integers specified
+                by the fifth argument is drawn from left to right in the
+                specified color. (See gdImageStringUp16 for a way of
+                drawing vertical text.) Pixels not set by a particular
+                character retain their previous color.
                 
                 This function was added in gd1.3 to provide a means of
                 rendering fonts with more than 256 characters for those
                 who have them. A more frequently used routine is
-                [261]gdImageString.
+                gdImageString.
                 
         void gdImageStringUp(gdImagePtr im, gdFontPtr font, int x, int y,
                 unsigned char *s, int color) _(FUNCTION)_
                 gdImageStringUp is used to draw multiple characters on
                 the image, rotated 90 degrees. (To draw single
-                characters, use [262]gdImageCharUp.) The second argument
-                is a pointer to a font definition structure; five fonts
-                are provided with gd, gdFontTiny, gdFontSmall,
+                characters, use gdImageCharUp.) The second argument is a
+                pointer to a font definition structure; five fonts are
+                provided with gd, gdFontTiny, gdFontSmall,
                 gdFontMediumBold, gdFontLarge, and gdFontGiant. You must
                 include the files "gdfontt.h", "gdfonts.h", "gdfontmb.h",
                 "gdfontl.h" and "gdfontg.h" respectively and (if you are
                 corresponding .c files to use the provided fonts.The
                 null-terminated C string specified by the fifth argument
                 is drawn from bottom to top (rotated 90 degrees) in the
-                specified color. (See [263]gdImageString for a way of
-                drawing horizontal text.) Pixels not set by a particular
+                specified color. (See gdImageString for a way of drawing
+                horizontal text.) Pixels not