]> granicus.if.org Git - php/commitdiff
Merge changes from GD 2.0.28
authorStefan Esser <sesser@php.net>
Thu, 22 Jul 2004 22:38:59 +0000 (22:38 +0000)
committerStefan Esser <sesser@php.net>
Thu, 22 Jul 2004 22:38:59 +0000 (22:38 +0000)
ext/gd/config.m4
ext/gd/config.w32
ext/gd/gd.dsp
ext/gd/libgd/gd.h
ext/gd/libgd/gd_gif_out.c [new file with mode: 0644]
ext/gd/libgd/gd_topal.c

index 05e406cb0b603d4ee4418797700e900c799b08c7..5c24407f4f8641e5ac45924f6475727dda5d2c8e 100644 (file)
@@ -272,7 +272,7 @@ if test "$PHP_GD" = "yes"; then
                  libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c libgd/gdfontmb.c libgd/gdfontl.c \
                  libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c libgd/gdcache.c libgd/gdkanji.c \
                  libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c libgd/gd_topal.c libgd/gd_gif_in.c \
-                 libgd/xbm.c"
+                 libgd/xbm.c libgd/gd_gif_out.c "
 
 dnl check for fabsf and floorf which are available since C99
   AC_CHECK_FUNCS(fabsf floorf)
@@ -306,6 +306,7 @@ dnl These are always available with bundled library
   AC_DEFINE(HAVE_GD_XBM,              1, [ ])
   AC_DEFINE(HAVE_GD_BUNDLED,          1, [ ])
   AC_DEFINE(HAVE_GD_GIF_READ,         1, [ ])
+  AC_DEFINE(HAVE_GD_GIF_CREATE,       1, [ ])
   AC_DEFINE(HAVE_GD_IMAGEELLIPSE,     1, [ ])
 
 dnl Make sure the libgd/ is first in the include path
index 3d9b375a50c4b2c11604e1ac7bd2854b843becde..0a0c9f6e50fd9527725a864b672aaa4c55e7e4fd 100644 (file)
@@ -13,7 +13,7 @@ if (PHP_GD != "no") {
                EXTENSION("gd", "gd.c gdttf.c", null, "-Iext/gd/libgd", "php_gd2.dll");
                ADD_SOURCES("ext/gd/libgd", "gd2copypal.c gd_arc_f_buggy.c gd.c \
                        gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
-                       gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gdhelpers.c gd_io.c gd_io_dp.c \
+                       gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
                        gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
                        gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c", "gd");
                AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
@@ -21,6 +21,7 @@ if (PHP_GD != "no") {
 /D HAVE_GD_BUNDLED=1  \
 /D HAVE_GD_GD2  \
 /D HAVE_GD_GIF_READ=1  \
+/D HAVE_GD_GIF_CREATE=1  \
 /D HAVE_GDIMAGECOLORRESOLVE=1  \
 /D HAVE_GD_IMAGESETBRUSH=1  \
 /D HAVE_GD_IMAGESETTILE=1 \
index d787286c7ef2661b9482840600bdda5527984865..3b9c695aec7984b1bd058b73f1712d58168dab87 100644 (file)
@@ -213,6 +213,10 @@ SOURCE=.\libgd\gd_gd2.c
 SOURCE=.\libgd\gd_gif_in.c\r
 # End Source File\r
 # Begin Source File\r
+
+SOURCE=.\libgd\gd_gif_out.c\r
+# End Source File\r
+# Begin Source File\r
 \r
 SOURCE=.\libgd\gd_io.c\r
 \r
index f0fdb6b284cd55bcb5a8d42798c4232b07c3097f..c7e12ac6355cce1dbbed833407233f246ec62461 100644 (file)
@@ -407,8 +407,11 @@ void gdImageColorDeallocate(gdImagePtr im, int color);
         conversion to palette is not great (for small images
         it can be negative) and the quality loss is ugly. */
 
+gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted);
+
 void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted);
 
+
 /* An attempt at getting the results of gdImageTrueColorToPalette
        to look a bit more like the original (im1 is the original
        and im2 is the palette version */
@@ -428,6 +431,8 @@ void gdImageColorTransparent(gdImagePtr im, int color);
 void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src);
 void gdImagePng(gdImagePtr im, FILE *out);
 void gdImagePngCtx(gdImagePtr im, gdIOCtx *out);
+void gdImageGif(gdImagePtr im, FILE *out);
+void gdImageGifCtx(gdImagePtr im, gdIOCtx *out);
 /* 2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all,
  * 1 is FASTEST but produces larger files, 9 provides the best
  * compression (smallest files) but takes a long time to compress, and
diff --git a/ext/gd/libgd/gd_gif_out.c b/ext/gd/libgd/gd_gif_out.c
new file mode 100644 (file)
index 0000000..49da75f
--- /dev/null
@@ -0,0 +1,759 @@
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include "gd.h"
+
+/* 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.
+*/
+
+/*
+ * a code_int must be able to hold 2**GIFBITS values of type int, and also -1
+ */
+typedef int             code_int;
+
+#ifdef SIGNED_COMPARE_SLOW
+typedef unsigned long int count_int;
+typedef unsigned short int count_short;
+#else /*SIGNED_COMPARE_SLOW*/
+typedef long int          count_int;
+#endif /*SIGNED_COMPARE_SLOW*/
+
+/* 2.0.28: threadsafe */
+
+#define maxbits GIFBITS
+
+/* should NEVER generate this code */
+#define maxmaxcode ((code_int)1 << GIFBITS)
+
+#define HSIZE  5003            /* 80% occupancy */
+#define hsize HSIZE            /* Apparently invariant, left over from 
+                                       compress */
+
+typedef struct {
+       int Width, Height;
+       int curx, cury;
+       long CountDown;
+       int Pass;
+       int Interlace;
+        int n_bits;                        /* number of bits/code */
+        code_int maxcode;                  /* maximum code, given n_bits */
+        count_int htab [HSIZE];
+        unsigned short codetab [HSIZE];
+       code_int free_ent;                  /* first unused entry */
+       /*
+        * block compression parameters -- after all codes are used up,
+        * and compression rate changes, start over.
+        */
+       int clear_flg;
+       int offset;
+       long int in_count;            /* length of input */
+       long int out_count;           /* # of codes output (for debugging) */
+
+       int g_init_bits;
+       gdIOCtx * g_outfile;
+
+       int ClearCode;
+       int EOFCode;
+       unsigned long cur_accum;
+       int cur_bits;
+        /*
+         * Number of characters so far in this 'packet'
+         */
+        int a_count;
+        /*
+         * Define the storage for the packet accumulator
+         */
+        char accum[ 256 ];
+} GifCtx;
+
+static int gifPutWord(int w, gdIOCtx *out);
+static int colorstobpp(int colors);
+static void BumpPixel (GifCtx *ctx);
+static int GIFNextPixel (gdImagePtr im, GifCtx *ctx);
+static void GIFEncode (gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im);
+static void compress (int init_bits, gdIOCtx *outfile, gdImagePtr im, GifCtx *ctx);
+static void output (code_int code, GifCtx *ctx);
+static void cl_block (GifCtx *ctx);
+static void cl_hash (register count_int chsize, GifCtx *ctx);
+static void char_init (GifCtx *ctx);
+static void char_out (int c, GifCtx *ctx);
+static void flush_char (GifCtx *ctx);
+void * gdImageGifPtr (gdImagePtr im, int *size)
+{
+  void *rv;
+  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
+  gdImageGifCtx (im, out);
+  rv = gdDPExtractData (out, size);
+  out->gd_free (out);
+  return rv;
+}
+
+void gdImageGif (gdImagePtr im, FILE * outFile)
+{
+  gdIOCtx *out = gdNewFileCtx (outFile);
+  gdImageGifCtx (im, out);
+  out->gd_free (out);
+}
+
+void gdImageGifCtx(gdImagePtr im, gdIOCtxPtr out)
+{
+       gdImagePtr pim = 0, tim = im;
+       int interlace, transparent, BitsPerPixel;
+       interlace = im->interlace;
+       transparent = im->transparent;
+       if (im->trueColor) {
+               /* Expensive, but the only way that produces an
+                       acceptable result: mix down to a palette
+                       based temporary image. */
+               pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
+               if (!pim) {
+                       return;
+               }
+               tim = pim; 
+       }
+       BitsPerPixel = colorstobpp(tim->colorsTotal);
+       /* All set, let's do it. */
+       GIFEncode(
+               out, tim->sx, tim->sy, interlace, 0, transparent, BitsPerPixel,
+               tim->red, tim->green, tim->blue, tim);
+       if (pim) {
+               /* Destroy palette based temporary image. */
+               gdImageDestroy( pim);
+       }
+}
+
+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
+/*
+ * Bump the 'curx' and 'cury' to point to the next pixel
+ */
+static void
+BumpPixel(GifCtx *ctx)
+{
+        /*
+         * Bump the current X position
+         */
+        ++(ctx->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( ctx->curx == ctx->Width ) {
+                ctx->curx = 0;
+
+                if( !ctx->Interlace )
+                        ++(ctx->cury);
+                else {
+                     switch( ctx->Pass ) {
+
+                       case 0:
+                          ctx->cury += 8;
+                          if( ctx->cury >= ctx->Height ) {
+                                ++(ctx->Pass);
+                                ctx->cury = 4;
+                          }
+                          break;
+
+                       case 1:
+                          ctx->cury += 8;
+                          if( ctx->cury >= ctx->Height ) {
+                                ++(ctx->Pass);
+                                ctx->cury = 2;
+                          }
+                          break;
+
+                       case 2:
+                          ctx->cury += 4;
+                          if( ctx->cury >= ctx->Height ) {
+                             ++(ctx->Pass);
+                             ctx->cury = 1;
+                          }
+                          break;
+
+                       case 3:
+                          ctx->cury += 2;
+                          break;
+                        }
+                }
+        }
+}
+
+/*
+ * Return the next pixel from the image
+ */
+static int
+GIFNextPixel(gdImagePtr im, GifCtx *ctx)
+{
+        int r;
+
+        if( ctx->CountDown == 0 )
+                return EOF;
+
+        --(ctx->CountDown);
+
+        r = gdImageGetPixel(im, ctx->curx, ctx->cury);
+
+        BumpPixel(ctx);
+
+        return r;
+}
+
+/* public */
+
+static void
+GIFEncode(gdIOCtxPtr 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;
+       GifCtx ctx;
+        ctx.Interlace = GInterlace;
+       ctx.in_count = 1;
+       memset(&ctx, 0, sizeof(ctx));
+        ColorMapSize = 1 << BitsPerPixel;
+
+        RWidth = ctx.Width = GWidth;
+        RHeight = ctx.Height = GHeight;
+        LeftOfs = TopOfs = 0;
+
+        Resolution = BitsPerPixel;
+
+        /*
+         * Calculate number of bits we are expecting
+         */
+        ctx.CountDown = (long)ctx.Width * (long)ctx.Height;
+
+        /*
+         * Indicate which pass we are on (if interlace)
+         */
+        ctx.Pass = 0;
+
+        /*
+         * The initial code size
+         */
+        if( BitsPerPixel <= 1 )
+                InitCodeSize = 2;
+        else
+                InitCodeSize = BitsPerPixel;
+
+        /*
+         * Set up the current x and y position
+         */
+        ctx.curx = ctx.cury = 0;
+
+        /*
+         * Write the Magic header
+         */
+        gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );
+
+        /*
+         * Write out the screen width and height
+         */
+        gifPutWord( RWidth, fp );
+        gifPutWord( RHeight, fp );
+
+        /*
+         * Indicate that there is a global colour map
+         */
+        B = 0x80;       /* Yes, there is a color map */
+
+        /*
+         * OR in the resolution
+         */
+        B |= (Resolution - 1) << 5;
+
+        /*
+         * OR in the Bits per Pixel
+         */
+        B |= (BitsPerPixel - 1);
+
+        /*
+         * Write it out
+         */
+        gdPutC( B, fp );
+
+        /*
+         * Write out the Background colour
+         */
+        gdPutC( Background, fp );
+
+        /*
+         * Byte of 0's (future expansion)
+         */
+        gdPutC( 0, fp );
+
+        /*
+         * Write out the Global Colour Map
+         */
+        for( i=0; i<ColorMapSize; ++i ) {
+                gdPutC( Red[i], fp );
+                gdPutC( Green[i], fp );
+                gdPutC( Blue[i], fp );
+        }
+
+       /*
+        * Write out extension for transparent colour index, if necessary.
+        */
+       if ( Transparent >= 0 ) {
+           gdPutC( '!', fp );
+           gdPutC( 0xf9, fp );
+           gdPutC( 4, fp );
+           gdPutC( 1, fp );
+           gdPutC( 0, fp );
+           gdPutC( 0, fp );
+           gdPutC( (unsigned char) Transparent, fp );
+           gdPutC( 0, fp );
+       }
+
+        /*
+         * Write an Image separator
+         */
+        gdPutC( ',', fp );
+
+        /*
+         * Write the Image header
+         */
+
+        gifPutWord( LeftOfs, fp );
+        gifPutWord( TopOfs, fp );
+        gifPutWord( ctx.Width, fp );
+        gifPutWord( ctx.Height, fp );
+
+        /*
+         * Write out whether or not the image is interlaced
+         */
+        if( ctx.Interlace )
+                gdPutC( 0x40, fp );
+        else
+                gdPutC( 0x00, fp );
+
+        /*
+         * Write out the initial code size
+         */
+        gdPutC( InitCodeSize, fp );
+
+        /*
+         * Go and actually compress the data
+         */
+        compress( InitCodeSize+1, fp, im, &ctx );
+
+        /*
+         * Write out a Zero-length packet (to end the series)
+         */
+        gdPutC( 0, fp );
+
+        /*
+         * Write the GIF file terminator
+         */
+        gdPutC( ';', fp );
+}
+
+/***************************************************************************
+ *
+ *  GIFCOMPR.C       - GIF Image compression routines
+ *
+ *  Lempel-Ziv compression based on 'compress'.  GIF modifications by
+ *  David Rowley (mgardi@watdcsu.waterloo.edu)
+ *
+ ***************************************************************************/
+
+/*
+ * General DEFINEs
+ */
+
+#define GIFBITS    12
+
+#ifdef NO_UCHAR
+ typedef char   char_type;
+#else /*NO_UCHAR*/
+ typedef        unsigned char   char_type;
+#endif /*NO_UCHAR*/
+
+/*
+ *
+ * GIF Image compression - modified 'compress'
+ *
+ * Based on: compress.c - File compression ala IEEE Computer, June 1984.
+ *
+ * By Authors:  Spencer W. Thomas       (decvax!harpo!utah-cs!utah-gr!thomas)
+ *              Jim McKie               (decvax!mcvax!jim)
+ *              Steve Davies            (decvax!vax135!petsd!peora!srd)
+ *              Ken Turkowski           (decvax!decwrl!turtlevax!ken)
+ *              James A. Woods          (decvax!ihnp4!ames!jaw)
+ *              Joe Orost               (decvax!vax135!petsd!joe)
+ *
+ */
+#include <ctype.h>
+
+#define ARGVAL() (*++(*argv) || (--argc && *++argv))
+
+#ifdef COMPATIBLE               /* But wrong! */
+# define MAXCODE(n_bits)        ((code_int) 1 << (n_bits) - 1)
+#else /*COMPATIBLE*/
+# define MAXCODE(n_bits)        (((code_int) 1 << (n_bits)) - 1)
+#endif /*COMPATIBLE*/
+
+#define HashTabOf(i)       ctx->htab[i]
+#define CodeTabOf(i)    ctx->codetab[i]
+
+
+/*
+ * To save much memory, we overlay the table used by compress() with those
+ * used by decompress().  The tab_prefix table is the same size and type
+ * as the codetab.  The tab_suffix table needs 2**GIFBITS characters.  We
+ * get this from the beginning of htab.  The output stack uses the rest
+ * of htab, and contains characters.  There is plenty of room for any
+ * possible stack (stack used to be 8000 characters).
+ */
+
+#define tab_prefixof(i) CodeTabOf(i)
+#define tab_suffixof(i)        ((char_type*)(htab))[i]
+#define de_stack               ((char_type*)&tab_suffixof((code_int)1<<GIFBITS))
+
+/*
+ * compress stdin to stdout
+ *
+ * Algorithm:  use open addressing double hashing (no chaining) on the
+ * prefix code / next character combination.  We do a variant of Knuth's
+ * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ * secondary probe.  Here, the modular division first probe is gives way
+ * to a faster exclusive-or manipulation.  Also do block compression with
+ * an adaptive reset, whereby the code table is cleared when the compression
+ * ratio decreases, but after the table fills.  The variable-length output
+ * codes are re-sized at this point, and a special CLEAR code is generated
+ * for the decompressor.  Late addition:  construct the table according to
+ * file size for noticeable speed improvement on small files.  Please direct
+ * questions about this implementation to ames!jaw.
+ */
+
+static void
+output(code_int code, GifCtx *ctx);
+
+static void
+compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *ctx)
+{
+    register long fcode;
+    register code_int i /* = 0 */;
+    register int c;
+    register code_int ent;
+    register code_int disp;
+    register code_int hsize_reg;
+    register int hshift;
+
+    /*
+     * Set up the globals:  g_init_bits - initial number of bits
+     *                      g_outfile   - pointer to output file
+     */
+    ctx->g_init_bits = init_bits;
+    ctx->g_outfile = outfile;
+
+    /*
+     * Set up the necessary values
+     */
+    ctx->offset = 0;
+    ctx->out_count = 0;
+    ctx->clear_flg = 0;
+    ctx->in_count = 1;
+    ctx->maxcode = MAXCODE(ctx->n_bits = ctx->g_init_bits);
+
+    ctx->ClearCode = (1 << (init_bits - 1));
+    ctx->EOFCode = ctx->ClearCode + 1;
+    ctx->free_ent = ctx->ClearCode + 2;
+
+    char_init(ctx);
+
+    ent = GIFNextPixel( im, ctx );
+
+    hshift = 0;
+    for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
+        ++hshift;
+    hshift = 8 - hshift;                /* set hash code range bound */
+
+    hsize_reg = hsize;
+    cl_hash( (count_int) hsize_reg, ctx );            /* clear hash table */
+
+    output( (code_int)ctx->ClearCode, ctx );
+
+#ifdef SIGNED_COMPARE_SLOW
+    while ( (c = GIFNextPixel( im )) != (unsigned) EOF ) {
+#else /*SIGNED_COMPARE_SLOW*/
+    while ( (c = GIFNextPixel( im, ctx )) != EOF ) {  /* } */
+#endif /*SIGNED_COMPARE_SLOW*/
+
+        ++(ctx->in_count);
+
+        fcode = (long) (((long) c << maxbits) + ent);
+        i = (((code_int)c << hshift) ^ ent);    /* xor hashing */
+
+        if ( HashTabOf (i) == fcode ) {
+            ent = CodeTabOf (i);
+            continue;
+        } else if ( (long)HashTabOf (i) < 0 )      /* empty slot */
+            goto nomatch;
+        disp = hsize_reg - i;           /* secondary hash (after G. Knott) */
+        if ( i == 0 )
+            disp = 1;
+probe:
+        if ( (i -= disp) < 0 )
+            i += hsize_reg;
+
+        if ( HashTabOf (i) == fcode ) {
+            ent = CodeTabOf (i);
+            continue;
+        }
+        if ( (long)HashTabOf (i) > 0 )
+            goto probe;
+nomatch:
+        output ( (code_int) ent, ctx );
+        ++(ctx->out_count);
+        ent = c;
+#ifdef SIGNED_COMPARE_SLOW
+        if ( (unsigned) ctx->free_ent < (unsigned) maxmaxcode) {
+#else /*SIGNED_COMPARE_SLOW*/
+        if ( ctx->free_ent < maxmaxcode ) {  /* } */
+#endif /*SIGNED_COMPARE_SLOW*/
+            CodeTabOf (i) = ctx->free_ent++; /* code -> hashtable */
+            HashTabOf (i) = fcode;
+        } else
+                cl_block(ctx);
+    }
+    /*
+     * Put out the final code.
+     */
+    output( (code_int)ent, ctx );
+    ++(ctx->out_count);
+    output( (code_int) ctx->EOFCode, ctx );
+}
+
+/*****************************************************************
+ * TAG( output )
+ *
+ * Output the given code.
+ * Inputs:
+ *      code:   A n_bits-bit integer.  If == -1, then EOF.  This assumes
+ *              that n_bits =< (long)wordsize - 1.
+ * Outputs:
+ *      Outputs code to the file.
+ * Assumptions:
+ *      Chars are 8 bits long.
+ * Algorithm:
+ *      Maintain a GIFBITS character long buffer (so that 8 codes will
+ * fit in it exactly).  Use the VAX insv instruction to insert each
+ * code in turn.  When the buffer fills up empty it and start over.
+ */
+
+static unsigned long masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
+                                  0x001F, 0x003F, 0x007F, 0x00FF,
+                                  0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+                                  0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
+
+static void
+output(code_int code, GifCtx *ctx)
+{
+    ctx->cur_accum &= masks[ ctx->cur_bits ];
+
+    if( ctx->cur_bits > 0 )
+        ctx->cur_accum |= ((long)code << ctx->cur_bits);
+    else
+        ctx->cur_accum = code;
+
+    ctx->cur_bits += ctx->n_bits;
+
+    while( ctx->cur_bits >= 8 ) {
+        char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx );
+        ctx->cur_accum >>= 8;
+        ctx->cur_bits -= 8;
+    }
+
+    /*
+     * If the next entry is going to be too big for the code size,
+     * then increase it, if possible.
+     */
+   if ( ctx->free_ent > ctx->maxcode || ctx->clear_flg ) {
+
+            if( ctx->clear_flg ) {
+
+                ctx->maxcode = MAXCODE (ctx->n_bits = ctx->g_init_bits);
+                ctx->clear_flg = 0;
+
+            } else {
+
+                ++(ctx->n_bits);
+                if ( ctx->n_bits == maxbits )
+                    ctx->maxcode = maxmaxcode;
+                else
+                    ctx->maxcode = MAXCODE(ctx->n_bits);
+            }
+        }
+
+    if( code == ctx->EOFCode ) {
+        /*
+         * At EOF, write the rest of the buffer.
+         */
+        while( ctx->cur_bits > 0 ) {
+                char_out( (unsigned int)(ctx->cur_accum & 0xff), ctx);
+                ctx->cur_accum >>= 8;
+                ctx->cur_bits -= 8;
+        }
+
+        flush_char(ctx);
+
+    }
+}
+
+/*
+ * Clear out the hash table
+ */
+static void
+cl_block (GifCtx *ctx)             /* table clear for block compress */
+{
+
+        cl_hash ( (count_int) hsize, ctx );
+        ctx->free_ent = ctx->ClearCode + 2;
+        ctx->clear_flg = 1;
+
+        output( (code_int)ctx->ClearCode, ctx);
+}
+
+static void
+cl_hash(register count_int chsize, GifCtx *ctx)          /* reset code table */
+                         
+{
+
+        register count_int *htab_p = ctx->htab+chsize;
+
+        register long i;
+        register long m1 = -1;
+
+        i = chsize - 16;
+        do {                            /* might use Sys V memset(3) here */
+                *(htab_p-16) = m1;
+                *(htab_p-15) = m1;
+                *(htab_p-14) = m1;
+                *(htab_p-13) = m1;
+                *(htab_p-12) = m1;
+                *(htab_p-11) = m1;
+                *(htab_p-10) = m1;
+                *(htab_p-9) = m1;
+                *(htab_p-8) = m1;
+                *(htab_p-7) = m1;
+                *(htab_p-6) = m1;
+                *(htab_p-5) = m1;
+                *(htab_p-4) = m1;
+                *(htab_p-3) = m1;
+                *(htab_p-2) = m1;
+                *(htab_p-1) = m1;
+                htab_p -= 16;
+        } while ((i -= 16) >= 0);
+
+        for ( i += 16; i > 0; --i )
+                *--htab_p = m1;
+}
+
+/******************************************************************************
+ *
+ * GIF Specific routines
+ *
+ ******************************************************************************/
+
+/*
+ * Set up the 'byte output' routine
+ */
+static void
+char_init(GifCtx *ctx)
+{
+        ctx->a_count = 0;
+}
+
+/*
+ * Add a character to the end of the current packet, and if it is 254
+ * characters, flush the packet to disk.
+ */
+static void
+char_out(int c, GifCtx *ctx)
+{
+        ctx->accum[ ctx->a_count++ ] = c;
+        if( ctx->a_count >= 254 )
+                flush_char(ctx);
+}
+
+/*
+ * Flush the packet to disk, and reset the accumulator
+ */
+static void
+flush_char(GifCtx *ctx)
+{
+        if( ctx->a_count > 0 ) {
+                gdPutC( ctx->a_count, ctx->g_outfile );
+                gdPutBuf( ctx->accum, ctx->a_count, ctx->g_outfile );
+                ctx->a_count = 0;
+        }
+}
+
+static int gifPutWord(int w, gdIOCtx *out)
+{
+       /* Byte order is little-endian */
+       gdPutC(w & 0xFF, out);
+       gdPutC((w >> 8) & 0xFF, out);
+       return 0;
+}
+
+
index 60dbb6de65612a66ea79cafad9701d21243e381c..cdd90550887cf8af388ac6d12b8e7707cd01191d 100644 (file)
@@ -1,11 +1,13 @@
+/* TODO: oim and nim in the lower level functions;
+  correct use of stub (sigh). */
+
 /* 2.0.12: a new adaptation from the same original, this time
- * by Barend Gahrels. My attempt to incorporate alpha channel
- * into the result worked poorly and degraded the quality of
- * palette conversion even when the source contained no
- * alpha channel data. This version does not attempt to produce
- * an output file with transparency in some of the palette
- * indexes, which, in practice, doesn't look so hot anyway. TBB
- */
+       by Barend Gehrels. My attempt to incorporate alpha channel
+       into the result worked poorly and degraded the quality of
+       palette conversion even when the source contained no
+       alpha channel data. This version does not attempt to produce
+       an output file with transparency in some of the palette
+       indexes, which, in practice, doesn't look so hot anyway. TBB */
 
 /*
  * gd_topal, adapted from jquant2.c
  * If it is not working, it's not Thomas G. Lane's fault.
  */
 
-/*
* SETTING THIS ONE CAUSES STRIPED IMAGE
 to be done: solve this
* #define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS
+/* 
+  SETTING THIS ONE CAUSES STRIPED IMAGE
+  to be done: solve this
+  #define ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS
  */
 
+#include <string.h>
 #include "gd.h"
 #include "gdhelpers.h"
-#include <string.h>
-#include <stdlib.h>
 
 /* (Re)define some defines known by libjpeg */
 #define QUANT_2PASS_SUPPORTED
 #define FAR
 #endif
 
+
+
 #ifndef boolean
 #define boolean int
 #endif
 #define FALSE 0
 #endif
 
-#define input_buf (im->tpixels)
-#define output_buf (im->pixels)
+
+#define input_buf (oim->tpixels)
+#define output_buf (nim->pixels)
 
 #endif
 
  * color space, and repeatedly splits the "largest" remaining box until we
  * have as many boxes as desired colors.  Then the mean color in each
  * remaining box becomes one of the possible output colors.
- *
+ * 
  * The second pass over the image maps each input pixel to the closest output
  * color (optionally after applying a Floyd-Steinberg dithering correction).
  * This mapping is logically trivial, but making it go fast enough requires
@@ -294,32 +298,34 @@ typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
 
 typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
 
+
 /* Private subobject */
 
 typedef struct
 {
 #ifdef ORIGINAL_LIB_JPEG
-       struct jpeg_color_quantizer pub;        /* public fields */
+  struct jpeg_color_quantizer pub;     /* public fields */
 
-       /* Space for the eventually created colormap is stashed here */
-       JSAMPARRAY sv_colormap; /* colormap allocated at init time */
-       int desired;            /* desired # of colors = size of colormap */
-       boolean needs_zeroed;   /* TRUE if next pass must zero histogram */
+  /* Space for the eventually created colormap is stashed here */
+  JSAMPARRAY sv_colormap;      /* colormap allocated at init time */
+  int desired;                 /* desired # of colors = size of colormap */
+  boolean needs_zeroed;                /* TRUE if next pass must zero histogram */
 #endif
 
-         /* Variables for accumulating image statistics */
-       hist3d histogram;       /* pointer to the histogram */
+  /* Variables for accumulating image statistics */
+  hist3d histogram;            /* pointer to the histogram */
 
 
-       /* Variables for Floyd-Steinberg dithering */
-       FSERRPTR fserrors;      /* accumulated errors */
+  /* Variables for Floyd-Steinberg dithering */
+  FSERRPTR fserrors;           /* accumulated errors */
 
-       boolean on_odd_row;     /* flag to remember which row we are on */
-       int *error_limiter;     /* table for clamping the applied error */
+  boolean on_odd_row;          /* flag to remember which row we are on */
+  int *error_limiter;          /* table for clamping the applied error */
 #ifndef ORIGINAL_LIB_JPEG
-       int *error_limiter_storage;     /* gdMalloc'd storage for the above */
+  int *error_limiter_storage;  /* gdMalloc'd storage for the above */
 #endif
-} my_cquantizer;
+}
+my_cquantizer;
 
 typedef my_cquantizer *my_cquantize_ptr;
 
@@ -335,57 +341,62 @@ typedef my_cquantizer *my_cquantize_ptr;
 
 METHODDEF (void)
 #ifndef ORIGINAL_LIB_JPEG
-prescan_quantize (gdImagePtr im, my_cquantize_ptr cquantize)
+prescan_quantize (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
 {
 #else
-prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+                 JSAMPARRAY output_buf, int num_rows)
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 #endif
-       register JSAMPROW ptr;
-       register histptr histp;
-       register hist3d histogram = cquantize->histogram;
-       int row;
-       JDIMENSION col;
+  register JSAMPROW ptr;
+  register histptr histp;
+  register hist3d histogram = cquantize->histogram;
+  int row;
+  JDIMENSION col;
 #ifdef ORIGINAL_LIB_JPEG
-       JDIMENSION width = cinfo->output_width;
+  JDIMENSION width = cinfo->output_width;
 #else
-       int width = im->sx;
-       int num_rows = im->sy;
+  int width = oim->sx;
+  int num_rows = oim->sy;
 #endif
 
-       for (row = 0; row < num_rows; row++) {
-               ptr = input_buf[row];
-               for (col = width; col > 0; col--) {
+  for (row = 0; row < num_rows; row++)
+    {
+      ptr = input_buf[row];
+      for (col = width; col > 0; col--)
+       {
 #ifdef ORIGINAL_LIB_JPEG
-                       int r = GETJSAMPLE(ptr[0]) >> C0_SHIFT;
-                       int g = GETJSAMPLE(ptr[1]) >> C1_SHIFT;
-                       int b = GETJSAMPLE(ptr[2]) >> C2_SHIFT;
+         int r = GETJSAMPLE (ptr[0]) >> C0_SHIFT;
+         int g = GETJSAMPLE (ptr[1]) >> C1_SHIFT;
+         int b = GETJSAMPLE (ptr[2]) >> C2_SHIFT;
 #else
-                       int r = gdTrueColorGetRed(*ptr) >> C0_SHIFT;
-                       int g = gdTrueColorGetGreen(*ptr) >> C1_SHIFT;
-                       int b = gdTrueColorGetBlue(*ptr) >> C2_SHIFT;
-                       /* 2.0.12: Steven Brown: support a single totally transparent color in the original. */
-                       if ((im->transparent >= 0) && (*ptr == im->transparent)) {
-                               ptr++;
-                               continue;
-                       }
+         int r = gdTrueColorGetRed (*ptr) >> C0_SHIFT;
+         int g = gdTrueColorGetGreen (*ptr) >> C1_SHIFT;
+         int b = gdTrueColorGetBlue (*ptr) >> C2_SHIFT;
+         /* 2.0.12: Steven Brown: support a single totally transparent
+            color in the original. */
+         if ((oim->transparent >= 0) && (*ptr == oim->transparent))
+           {
+             ptr++;
+             continue;
+           }
 #endif
-                       /* get pixel value and index into the histogram */
-                       histp = &histogram[r][g][b];
-                       /* increment, check for overflow and undo increment if so. */
-                       if (++(*histp) == 0) {
-                               (*histp)--;
-                       }
+         /* get pixel value and index into the histogram */
+         histp = &histogram[r][g][b];
+         /* increment, check for overflow and undo increment if so. */
+         if (++(*histp) == 0)
+           (*histp)--;
 #ifdef ORIGINAL_LIB_JPEG
-                       ptr += 3;
+         ptr += 3;
 #else
-                       ptr++;
+         ptr++;
 #endif
-               }
        }
+    }
 }
 
+
 /*
  * Next we have the really interesting routines: selection of a colormap
  * given the completed histogram.
@@ -395,35 +406,38 @@ prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY outpu
 
 typedef struct
 {
-       /* The bounds of the box (inclusive); expressed as histogram indexes */
-       int c0min, c0max;
-       int c1min, c1max;
-       int c2min, c2max;
-       /* The volume (actually 2-norm) of the box */
-       INT32 volume;
-       /* The number of nonzero histogram cells within this box */
-       long colorcount;
-} box;
+  /* The bounds of the box (inclusive); expressed as histogram indexes */
+  int c0min, c0max;
+  int c1min, c1max;
+  int c2min, c2max;
+  /* The volume (actually 2-norm) of the box */
+  INT32 volume;
+  /* The number of nonzero histogram cells within this box */
+  long colorcount;
+}
+box;
 
 typedef box *boxptr;
 
+
 LOCAL (boxptr) find_biggest_color_pop (boxptr boxlist, int numboxes)
 /* Find the splittable box with the largest color population */
 /* Returns NULL if no splittable boxes remain */
 {
-       register boxptr boxp;
-       register int i;
-       register long maxc = 0;
-       boxptr which = NULL;
-
-       for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
-               if (boxp->colorcount > maxc && boxp->volume > 0) {
-                       which = boxp;
-                       maxc = boxp->colorcount;
-               }
+  register boxptr boxp;
+  register int i;
+  register long maxc = 0;
+  boxptr which = NULL;
+
+  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
+    {
+      if (boxp->colorcount > maxc && boxp->volume > 0)
+       {
+         which = boxp;
+         maxc = boxp->colorcount;
        }
-
-       return which;
+    }
+  return which;
 }
 
 
@@ -431,320 +445,333 @@ LOCAL (boxptr) find_biggest_volume (boxptr boxlist, int numboxes)
 /* Find the splittable box with the largest (scaled) volume */
 /* Returns NULL if no splittable boxes remain */
 {
-       register boxptr boxp;
-       register int i;
-       register INT32 maxv = 0;
-       boxptr which = NULL;
-
-       for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
-               if (boxp->volume > maxv) {
-                       which = boxp;
-                       maxv = boxp->volume;
-               }
+  register boxptr boxp;
+  register int i;
+  register INT32 maxv = 0;
+  boxptr which = NULL;
+
+  for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
+    {
+      if (boxp->volume > maxv)
+       {
+         which = boxp;
+         maxv = boxp->volume;
        }
-
-       return which;
+    }
+  return which;
 }
 
 
 LOCAL (void)
 #ifndef ORIGINAL_LIB_JPEG
-  update_box (gdImagePtr im, my_cquantize_ptr cquantize, boxptr boxp)
+  update_box (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, boxptr boxp)
 {
 #else
   update_box (j_decompress_ptr cinfo, boxptr boxp)
 /* Shrink the min/max bounds of a box to enclose only nonzero elements, */
 /* and recompute its volume and population */
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 #endif
-       hist3d histogram = cquantize->histogram;
-       histptr histp;
-       int c0, c1, c2;
-       int c0min, c0max, c1min, c1max, c2min, c2max;
-       INT32 dist0, dist1, dist2;
-       long ccount;
-
-       c0min = boxp->c0min;
-       c0max = boxp->c0max;
-       c1min = boxp->c1min;
-       c1max = boxp->c1max;
-       c2min = boxp->c2min;
-       c2max = boxp->c2max;
-
-       if (c0max > c0min) {
-               for (c0 = c0min; c0 <= c0max; c0++) {
-                       for (c1 = c1min; c1 <= c1max; c1++) {
-                               histp = &histogram[c0][c1][c2min];
-                               for (c2 = c2min; c2 <= c2max; c2++) {
-                                       if (*histp++ != 0) {
-                                               boxp->c0min = c0min = c0;
-                                               goto have_c0min;
-                                       }
-                               }
-                       }
-               }
+  hist3d histogram = cquantize->histogram;
+  histptr histp;
+  int c0, c1, c2;
+  int c0min, c0max, c1min, c1max, c2min, c2max;
+  INT32 dist0, dist1, dist2;
+  long ccount;
+
+  c0min = boxp->c0min;
+  c0max = boxp->c0max;
+  c1min = boxp->c1min;
+  c1max = boxp->c1max;
+  c2min = boxp->c2min;
+  c2max = boxp->c2max;
+
+  if (c0max > c0min)
+    for (c0 = c0min; c0 <= c0max; c0++)
+      for (c1 = c1min; c1 <= c1max; c1++)
+       {
+         histp = &histogram[c0][c1][c2min];
+         for (c2 = c2min; c2 <= c2max; c2++)
+           if (*histp++ != 0)
+             {
+               boxp->c0min = c0min = c0;
+               goto have_c0min;
+             }
        }
 have_c0min:
-       if (c0max > c0min) {
-               for (c0 = c0max; c0 >= c0min; c0--) {
-                       for (c1 = c1min; c1 <= c1max; c1++) {
-                               histp = &histogram[c0][c1][c2min];
-                               for (c2 = c2min; c2 <= c2max; c2++) {
-                                       if (*histp++ != 0) {
-                                               boxp->c0max = c0max = c0;
-                                               goto have_c0max;
-                                       }
-                               }
-                       }
-               }
+  if (c0max > c0min)
+    for (c0 = c0max; c0 >= c0min; c0--)
+      for (c1 = c1min; c1 <= c1max; c1++)
+       {
+         histp = &histogram[c0][c1][c2min];
+         for (c2 = c2min; c2 <= c2max; c2++)
+           if (*histp++ != 0)
+             {
+               boxp->c0max = c0max = c0;
+               goto have_c0max;
+             }
        }
 have_c0max:
-       if (c1max > c1min) {
-               for (c1 = c1min; c1 <= c1max; c1++) {
-                       for (c0 = c0min; c0 <= c0max; c0++) {
-                               histp = &histogram[c0][c1][c2min];
-                               for (c2 = c2min; c2 <= c2max; c2++) {
-                                       if (*histp++ != 0) {
-                                               boxp->c1min = c1min = c1;
-                                               goto have_c1min;
-                                       }
-                               }
-                       }
-               }
+  if (c1max > c1min)
+    for (c1 = c1min; c1 <= c1max; c1++)
+      for (c0 = c0min; c0 <= c0max; c0++)
+       {
+         histp = &histogram[c0][c1][c2min];
+         for (c2 = c2min; c2 <= c2max; c2++)
+           if (*histp++ != 0)
+             {
+               boxp->c1min = c1min = c1;
+               goto have_c1min;
+             }
        }
 have_c1min:
-       if (c1max > c1min) {
-               for (c1 = c1max; c1 >= c1min; c1--) {
-                       for (c0 = c0min; c0 <= c0max; c0++) {
-                               histp = &histogram[c0][c1][c2min];
-                               for (c2 = c2min; c2 <= c2max; c2++) {
-                                       if (*histp++ != 0) {
-                                               boxp->c1max = c1max = c1;
-                                               goto have_c1max;
-                                       }
-                               }
-                       }
-               }
+  if (c1max > c1min)
+    for (c1 = c1max; c1 >= c1min; c1--)
+      for (c0 = c0min; c0 <= c0max; c0++)
+       {
+         histp = &histogram[c0][c1][c2min];
+         for (c2 = c2min; c2 <= c2max; c2++)
+           if (*histp++ != 0)
+             {
+               boxp->c1max = c1max = c1;
+               goto have_c1max;
+             }
        }
 have_c1max:
-       if (c2max > c2min) {
-               for (c2 = c2min; c2 <= c2max; c2++) {
-                       for (c0 = c0min; c0 <= c0max; c0++) {
-                               histp = &histogram[c0][c1min][c2];
-                               for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) {
-                                       if (*histp != 0) {
-                                               boxp->c2min = c2min = c2;
-                                               goto have_c2min;
-                                       }
-                               }
-                       }
-               }
+  if (c2max > c2min)
+    for (c2 = c2min; c2 <= c2max; c2++)
+      for (c0 = c0min; c0 <= c0max; c0++)
+       {
+         histp = &histogram[c0][c1min][c2];
+         for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+           if (*histp != 0)
+             {
+               boxp->c2min = c2min = c2;
+               goto have_c2min;
+             }
        }
 have_c2min:
-       if (c2max > c2min) {
-               for (c2 = c2max; c2 >= c2min; c2--) {
-                       for (c0 = c0min; c0 <= c0max; c0++) {
-                               histp = &histogram[c0][c1min][c2];
-                               for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) {
-                                       if (*histp != 0) {
-                                               boxp->c2max = c2max = c2;
-                                               goto have_c2max;
-                                       }
-                               }
-                       }
-               }
+  if (c2max > c2min)
+    for (c2 = c2max; c2 >= c2min; c2--)
+      for (c0 = c0min; c0 <= c0max; c0++)
+       {
+         histp = &histogram[c0][c1min][c2];
+         for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+           if (*histp != 0)
+             {
+               boxp->c2max = c2max = c2;
+               goto have_c2max;
+             }
        }
 have_c2max:
 
-       /* Update box volume.
-        * We use 2-norm rather than real volume here; this biases the method
-        * against making long narrow boxes, and it has the side benefit that
-        * a box is splittable iff norm > 0.
-        * Since the differences are expressed in histogram-cell units,
-        * we have to shift back to JSAMPLE units to get consistent distances;
-        * after which, we scale according to the selected distance scale factors.
-        */
-       dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
-       dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
-       dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
-       boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2;
-
-       /* Now scan remaining volume of box and compute population */
-       ccount = 0;
-       for (c0 = c0min; c0 <= c0max; c0++) {
-               for (c1 = c1min; c1 <= c1max; c1++) {
-                       histp = &histogram[c0][c1][c2min];
-                       for (c2 = c2min; c2 <= c2max; c2++, histp++) {
-                               if (*histp != 0) {
-                                       ccount++;
-                               }
-                       }
-               }
-       }
-       boxp->colorcount = ccount;
+  /* Update box volume.
+   * We use 2-norm rather than real volume here; this biases the method
+   * against making long narrow boxes, and it has the side benefit that
+   * a box is splittable iff norm > 0.
+   * Since the differences are expressed in histogram-cell units,
+   * we have to shift back to JSAMPLE units to get consistent distances;
+   * after which, we scale according to the selected distance scale factors.
+   */
+  dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
+  dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
+  dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
+  boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2;
+
+  /* Now scan remaining volume of box and compute population */
+  ccount = 0;
+  for (c0 = c0min; c0 <= c0max; c0++)
+    for (c1 = c1min; c1 <= c1max; c1++)
+      {
+       histp = &histogram[c0][c1][c2min];
+       for (c2 = c2min; c2 <= c2max; c2++, histp++)
+         if (*histp != 0)
+           {
+             ccount++;
+           }
+      }
+  boxp->colorcount = ccount;
 }
 
 
 LOCAL (int)
 #ifdef ORIGINAL_LIB_JPEG
-median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, int desired_colors)
+median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
+           int desired_colors)
 #else
-median_cut (gdImagePtr im, my_cquantize_ptr cquantize, boxptr boxlist, int numboxes, int desired_colors)
+median_cut (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize,
+           boxptr boxlist, int numboxes, int desired_colors)
 #endif
 /* Repeatedly select and split the largest box until we have enough boxes */
 {
-       int n, lb;
-       int c0, c1, c2, cmax;
-       register boxptr b1, b2;
-
-       while (numboxes < desired_colors) {
-               /* Select box to split.
-                * Current algorithm: by population for first half, then by volume.
-                */
-               if (numboxes * 2 <= desired_colors) {
-                       b1 = find_biggest_color_pop(boxlist, numboxes);
-               } else {
-                       b1 = find_biggest_volume(boxlist, numboxes);
-               }
-               if (b1 == NULL) { /* no splittable boxes left! */
-                       break;
-               }
-               b2 = &boxlist[numboxes];        /* where new box will go */
-               /* Copy the color bounds to the new box. */
-               b2->c0max = b1->c0max;
-               b2->c1max = b1->c1max;
-               b2->c2max = b1->c2max;
-               b2->c0min = b1->c0min;
-               b2->c1min = b1->c1min;
-               b2->c2min = b1->c2min;
-               /* Choose which axis to split the box on.
-                * Current algorithm: longest scaled axis.
-                * See notes in update_box about scaling distances.
-                */
-               c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
-               c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
-               c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
-               /* We want to break any ties in favor of green, then red, blue last.
-                * This code does the right thing for R,G,B or B,G,R color orders only.
-                */
+  int n, lb;
+  int c0, c1, c2, cmax;
+  register boxptr b1, b2;
+
+  while (numboxes < desired_colors)
+    {
+      /* Select box to split.
+       * Current algorithm: by population for first half, then by volume.
+       */
+      if (numboxes * 2 <= desired_colors)
+       {
+         b1 = find_biggest_color_pop (boxlist, numboxes);
+       }
+      else
+       {
+         b1 = find_biggest_volume (boxlist, numboxes);
+       }
+      if (b1 == NULL)          /* no splittable boxes left! */
+       break;
+      b2 = &boxlist[numboxes]; /* where new box will go */
+      /* Copy the color bounds to the new box. */
+      b2->c0max = b1->c0max;
+      b2->c1max = b1->c1max;
+      b2->c2max = b1->c2max;
+      b2->c0min = b1->c0min;
+      b2->c1min = b1->c1min;
+      b2->c2min = b1->c2min;
+      /* Choose which axis to split the box on.
+       * Current algorithm: longest scaled axis.
+       * See notes in update_box about scaling distances.
+       */
+      c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
+      c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
+      c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
+      /* We want to break any ties in favor of green, then red, blue last.
+       * This code does the right thing for R,G,B or B,G,R color orders only.
+       */
 #if RGB_RED == 0
-               cmax = c1;
-               n = 1;
-               if (c0 > cmax) {
-                       cmax = c0;
-                       n = 0;
-               }
-               if (c2 > cmax) {
-                       n = 2;
-               }
+      cmax = c1;
+      n = 1;
+      if (c0 > cmax)
+       {
+         cmax = c0;
+         n = 0;
+       }
+      if (c2 > cmax)
+       {
+         n = 2;
+       }
 #else
-               cmax = c1;
-               n = 1;
-               if (c2 > cmax) {
-                       cmax = c2;
-                       n = 2;
-               }
-               if (c0 > cmax) {
-                       n = 0;
-               }
+      cmax = c1;
+      n = 1;
+      if (c2 > cmax)
+       {
+         cmax = c2;
+         n = 2;
+       }
+      if (c0 > cmax)
+       {
+         n = 0;
+       }
 #endif
-               /* Choose split point along selected axis, and update box bounds.
-                * Current algorithm: split at halfway point.
-                * (Since the box has been shrunk to minimum volume,
-                * any split will produce two nonempty subboxes.)
-                * Note that lb value is max for lower box, so must be < old max.
-                */
-               switch (n) {
-                       case 0:
-                               lb = (b1->c0max + b1->c0min) / 2;
-                               b1->c0max = lb;
-                               b2->c0min = lb + 1;
-                               break;
-                       case 1:
-                               lb = (b1->c1max + b1->c1min) / 2;
-                               b1->c1max = lb;
-                               b2->c1min = lb + 1;
-                               break;
-                       case 2:
-                               lb = (b1->c2max + b1->c2min) / 2;
-                               b1->c2max = lb;
-                               b2->c2min = lb + 1;
-                               break;
-               }
-                       /* Update stats for boxes */
+      /* Choose split point along selected axis, and update box bounds.
+       * Current algorithm: split at halfway point.
+       * (Since the box has been shrunk to minimum volume,
+       * any split will produce two nonempty subboxes.)
+       * Note that lb value is max for lower box, so must be < old max.
+       */
+      switch (n)
+       {
+       case 0:
+         lb = (b1->c0max + b1->c0min) / 2;
+         b1->c0max = lb;
+         b2->c0min = lb + 1;
+         break;
+       case 1:
+         lb = (b1->c1max + b1->c1min) / 2;
+         b1->c1max = lb;
+         b2->c1min = lb + 1;
+         break;
+       case 2:
+         lb = (b1->c2max + b1->c2min) / 2;
+         b1->c2max = lb;
+         b2->c2min = lb + 1;
+         break;
+       }
+      /* Update stats for boxes */
 #ifdef ORIGINAL_LIB_JPEG
-               update_box(cinfo, b1);
-               update_box(cinfo, b2);
+      update_box (cinfo, b1);
+      update_box (cinfo, b2);
 #else
-               update_box(im, cquantize, b1);
-               update_box(im, cquantize, b2);
+      update_box (oim, nim, cquantize, b1);
+      update_box (oim, nim, cquantize, b2);
 #endif
-               numboxes++;
-       }
-
-       return numboxes;
+      numboxes++;
+    }
+  return numboxes;
 }
 
 
 LOCAL (void)
 #ifndef ORIGINAL_LIB_JPEG
- compute_color (gdImagePtr im, my_cquantize_ptr cquantize, boxptr boxp, int icolor)
+  compute_color (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize,
+              boxptr boxp, int icolor)
 {
 #else
- compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
 compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
 /* Compute representative color for a box, put it in colormap[icolor] */
 {
-       /* Current algorithm: mean weighted by pixels (not colors) */
-       /* Note it is important to get the rounding correct! */
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  /* Current algorithm: mean weighted by pixels (not colors) */
+  /* Note it is important to get the rounding correct! */
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 #endif
-       hist3d histogram = cquantize->histogram;
-       histptr histp;
-       int c0, c1, c2;
-       int c0min, c0max, c1min, c1max, c2min, c2max;
-       long count = 0;
-       long total = 0;
-       long c0total = 0;
-       long c1total = 0;
-       long c2total = 0;
-
-       c0min = boxp->c0min;
-       c0max = boxp->c0max;
-       c1min = boxp->c1min;
-       c1max = boxp->c1max;
-       c2min = boxp->c2min;
-       c2max = boxp->c2max;
-
-       for (c0 = c0min; c0 <= c0max; c0++) {
-               for (c1 = c1min; c1 <= c1max; c1++) {
-                       histp = &histogram[c0][c1][c2min];
-                       for (c2 = c2min; c2 <= c2max; c2++) {
-                               if ((count = *histp++) != 0) {
-                                       total += count;
-                                       c0total += ((c0 << C0_SHIFT) + ((1 << C0_SHIFT) >> 1)) * count;
-                                       c1total += ((c1 << C1_SHIFT) + ((1 << C1_SHIFT) >> 1)) * count;
-                                       c2total += ((c2 << C2_SHIFT) + ((1 << C2_SHIFT) >> 1)) * count;
-                               }
-                       }
-               }
-       }
+  hist3d histogram = cquantize->histogram;
+  histptr histp;
+  int c0, c1, c2;
+  int c0min, c0max, c1min, c1max, c2min, c2max;
+  long count = 0; /* 2.0.28: = 0 */
+  long total = 0;
+  long c0total = 0;
+  long c1total = 0;
+  long c2total = 0;
+
+  c0min = boxp->c0min;
+  c0max = boxp->c0max;
+  c1min = boxp->c1min;
+  c1max = boxp->c1max;
+  c2min = boxp->c2min;
+  c2max = boxp->c2max;
+
+  for (c0 = c0min; c0 <= c0max; c0++)
+    for (c1 = c1min; c1 <= c1max; c1++)
+      {
+       histp = &histogram[c0][c1][c2min];
+       for (c2 = c2min; c2 <= c2max; c2++)
+         {
+           if ((count = *histp++) != 0)
+             {
+               total += count;
+               c0total +=
+                 ((c0 << C0_SHIFT) + ((1 << C0_SHIFT) >> 1)) * count;
+               c1total +=
+                 ((c1 << C1_SHIFT) + ((1 << C1_SHIFT) >> 1)) * count;
+               c2total +=
+                 ((c2 << C2_SHIFT) + ((1 << C2_SHIFT) >> 1)) * count;
+             }
+         }
+      }
 
 #ifdef ORIGINAL_LIB_JPEG
-       cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total >> 1)) / total);
-       cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total >> 1)) / total);
-       cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total >> 1)) / total);
+  cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total >> 1)) / total);
+  cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total >> 1)) / total);
+  cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total >> 1)) / total);
 #else
-       /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */
-       if (count) {
-               im->red[icolor] = (int) ((c0total + (total >> 1)) / total);
-               im->green[icolor] = (int) ((c1total + (total >> 1)) / total);
-               im->blue[icolor] = (int) ((c2total + (total >> 1)) / total);
-       } else {
-               im->red[icolor] = 255;
-               im->green[icolor] = 255;
-               im->blue[icolor] = 255;
-       }
+  /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */
+  if (count)
+    {
+      nim->red[icolor] = (int) ((c0total + (total >> 1)) / total);
+      nim->green[icolor] = (int) ((c1total + (total >> 1)) / total);
+      nim->blue[icolor] = (int) ((c2total + (total >> 1)) / total);
+    }
+  else
+    {
+      nim->red[icolor] = 255;
+      nim->green[icolor] = 255;
+      nim->blue[icolor] = 255;
+    }
 #endif
 }
 
@@ -753,65 +780,64 @@ LOCAL (void)
 #ifdef ORIGINAL_LIB_JPEG
 select_colors (j_decompress_ptr cinfo, int desired_colors)
 #else
-select_colors (gdImagePtr im, my_cquantize_ptr cquantize, int desired_colors)
+select_colors (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize, int desired_colors)
 #endif
 /* Master routine for color selection */
 {
-       boxptr boxlist;
-       int numboxes;
-       int i;
+  boxptr boxlist;
+  int numboxes;
+  int i;
 
-       /* Allocate workspace for box list */
+  /* Allocate workspace for box list */
 #ifdef ORIGINAL_LIB_JPEG
-       boxlist = (boxptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF (box));
+  boxlist = (boxptr) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF (box));
 #else
-       boxlist = (boxptr) safe_emalloc(desired_colors, sizeof(box), 1);
+  boxlist = (boxptr) safe_emalloc(desired_colors, sizeof (box), 1);
 #endif
-       /* Initialize one box containing whole space */
-       numboxes = 1;
-       boxlist[0].c0min = 0;
-       boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
-       boxlist[0].c1min = 0;
-       boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
-       boxlist[0].c2min = 0;
-       boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
+  /* Initialize one box containing whole space */
+  numboxes = 1;
+  boxlist[0].c0min = 0;
+  boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
+  boxlist[0].c1min = 0;
+  boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
+  boxlist[0].c2min = 0;
+  boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
 #ifdef ORIGINAL_LIB_JPEG
-       /* Shrink it to actually-used volume and set its statistics */
-       update_box(cinfo, &boxlist[0]);
-       /* Perform median-cut to produce final box list */
-       numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
-       /* Compute the representative color for each box, fill colormap */
-       for (i = 0; i < numboxes; i++) {
-               compute_color(cinfo, &boxlist[i], i);
-       }
-       cinfo->actual_number_of_colors = numboxes;
-       TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
+  /* Shrink it to actually-used volume and set its statistics */
+  update_box (cinfo, &boxlist[0]);
+  /* Perform median-cut to produce final box list */
+  numboxes = median_cut (cinfo, boxlist, numboxes, desired_colors);
+  /* Compute the representative color for each box, fill colormap */
+  for (i = 0; i < numboxes; i++)
+    compute_color (cinfo, &boxlist[i], i);
+  cinfo->actual_number_of_colors = numboxes;
+  TRACEMS1 (cinfo, 1, JTRC_QUANT_SELECTED, numboxes);
 #else
-       /* Shrink it to actually-used volume and set its statistics */
-       update_box(im, cquantize, &boxlist[0]);
-       /* Perform median-cut to produce final box list */
-       numboxes = median_cut(im, cquantize, boxlist, numboxes, desired_colors);
-       /* Compute the representative color for each box, fill colormap */
-       for (i = 0; i < numboxes; i++) {
-               compute_color(im, cquantize, &boxlist[i], i);
-       }
-       im->colorsTotal = numboxes;
-
-       /* If we had a pure transparency color, add it as the last palette entry.
-        * Skip incrementing the color count so that the dither / matching phase
-        * won't use it on pixels that shouldn't have been transparent. We'll
-        * increment it after all that finishes.
-        */
-       if (im->transparent >= 0) {
-               /* Save the transparent color. */
-               im->red[im->colorsTotal] = gdTrueColorGetRed(im->transparent);
-               im->green[im->colorsTotal] = gdTrueColorGetGreen(im->transparent);
-               im->blue[im->colorsTotal] = gdTrueColorGetBlue(im->transparent);
-               im->alpha[im->colorsTotal] = gdAlphaTransparent;
-               im->open[im->colorsTotal] = 0;
-       }
-
-       gdFree(boxlist);
+  /* Shrink it to actually-used volume and set its statistics */
+  update_box (oim, nim, cquantize, &boxlist[0]);
+  /* Perform median-cut to produce final box list */
+  numboxes = median_cut (oim, nim, cquantize, boxlist, numboxes, desired_colors);
+  /* Compute the representative color for each box, fill colormap */
+  for (i = 0; i < numboxes; i++)
+    compute_color (oim, nim, cquantize, &boxlist[i], i);
+  nim->colorsTotal = numboxes;
+
+  /* If we had a pure transparency color, add it as the last palette entry.
+   * Skip incrementing the color count so that the dither / matching phase
+   * won't use it on pixels that shouldn't have been transparent.  We'll
+   * increment it after all that finishes. */
+  if (oim->transparent >= 0)
+    {
+      /* Save the transparent color. */
+      nim->red[nim->colorsTotal] = gdTrueColorGetRed (oim->transparent);
+      nim->green[nim->colorsTotal] = gdTrueColorGetGreen (oim->transparent);
+      nim->blue[nim->colorsTotal] = gdTrueColorGetBlue (oim->transparent);
+      nim->alpha[nim->colorsTotal] = gdAlphaTransparent;
+      nim->open[nim->colorsTotal] = 0;
+    }
+
+  gdFree (boxlist);
 #endif
 }
 
@@ -895,11 +921,11 @@ select_colors (gdImagePtr im, my_cquantize_ptr cquantize, int desired_colors)
 LOCAL (int)
 find_nearby_colors (
 #ifdef ORIGINAL_LIB_JPEG
-       j_decompress_ptr cinfo,
+                    j_decompress_ptr cinfo,
 #else
-       gdImagePtr im, my_cquantize_ptr cquantize,
+                    gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize,
 #endif
-       int minc0, int minc1, int minc2, JSAMPLE colorlist[])
+                    int minc0, int minc1, int minc2, JSAMPLE colorlist[])
 /* Locate the colormap entries close enough to an update box to be candidates
  * for the nearest entry to some cell(s) in the update box.  The update box
  * is specified by the center coordinates of its first cell.  The number of
@@ -910,148 +936,173 @@ find_nearby_colors (
  */
 {
 #ifdef ORIGINAL_LIB_JPEG
-       int numcolors = cinfo->actual_number_of_colors;
+  int numcolors = cinfo->actual_number_of_colors;
 #else
-       int numcolors = im->colorsTotal;
+  int numcolors = nim->colorsTotal;
 #endif
-       int maxc0, maxc1, maxc2;
-       int centerc0, centerc1, centerc2;
-       int i, x, ncolors;
-       INT32 minmaxdist, min_dist, max_dist, tdist;
-       INT32 mindist[MAXNUMCOLORS];    /* min distance to colormap entry i */
-
-       /* Compute true coordinates of update box's upper corner and center.
-        * Actually we compute the coordinates of the center of the upper-corner
-        * histogram cell, which are the upper bounds of the volume we care about.
-        * Note that since ">>" rounds down, the "center" values may be closer to
-        * min than to max; hence comparisons to them must be "<=", not "<".
-        */
-       maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
-       centerc0 = (minc0 + maxc0) >> 1;
-       maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
-       centerc1 = (minc1 + maxc1) >> 1;
-       maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
-       centerc2 = (minc2 + maxc2) >> 1;
-
-       /* For each color in colormap, find:
-        *  1. its minimum squared-distance to any point in the update box
-        *     (zero if color is within update box);
-        *  2. its maximum squared-distance to any point in the update box.
-        * Both of these can be found by considering only the corners of the box.
-        * We save the minimum distance for each color in mindist[];
-        * only the smallest maximum distance is of interest.
-        */
-       minmaxdist = 0x7FFFFFFFL;
-
-       for (i = 0; i < numcolors; i++) {
-               /* We compute the squared-c0-distance term, then add in the other two. */
+  int maxc0, maxc1, maxc2;
+  int centerc0, centerc1, centerc2;
+  int i, x, ncolors;
+  INT32 minmaxdist, min_dist, max_dist, tdist;
+  INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
+
+  /* Compute true coordinates of update box's upper corner and center.
+   * Actually we compute the coordinates of the center of the upper-corner
+   * histogram cell, which are the upper bounds of the volume we care about.
+   * Note that since ">>" rounds down, the "center" values may be closer to
+   * min than to max; hence comparisons to them must be "<=", not "<".
+   */
+  maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
+  centerc0 = (minc0 + maxc0) >> 1;
+  maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
+  centerc1 = (minc1 + maxc1) >> 1;
+  maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
+  centerc2 = (minc2 + maxc2) >> 1;
+
+  /* For each color in colormap, find:
+   *  1. its minimum squared-distance to any point in the update box
+   *     (zero if color is within update box);
+   *  2. its maximum squared-distance to any point in the update box.
+   * Both of these can be found by considering only the corners of the box.
+   * We save the minimum distance for each color in mindist[];
+   * only the smallest maximum distance is of interest.
+   */
+  minmaxdist = 0x7FFFFFFFL;
+
+  for (i = 0; i < numcolors; i++)
+    {
+      /* We compute the squared-c0-distance term, then add in the other two. */
 #ifdef ORIGINAL_LIB_JPEG
-               x = GETJSAMPLE(cinfo->colormap[0][i]);
+      x = GETJSAMPLE (cinfo->colormap[0][i]);
 #else
-               x = im->red[i];
+      x = nim->red[i];
 #endif
-               if (x < minc0) {
-                       tdist = (x - minc0) * C0_SCALE;
-                       min_dist = tdist * tdist;
-                       tdist = (x - maxc0) * C0_SCALE;
-                       max_dist = tdist * tdist;
-               } else if (x > maxc0) {
-                       tdist = (x - maxc0) * C0_SCALE;
-                       min_dist = tdist * tdist;
-                       tdist = (x - minc0) * C0_SCALE;
-                       max_dist = tdist * tdist;
-               } else {
-                       /* within cell range so no contribution to min_dist */
-                       min_dist = 0;
-                       if (x <= centerc0) {
-                               tdist = (x - maxc0) * C0_SCALE;
-                               max_dist = tdist * tdist;
-                       } else {
-                               tdist = (x - minc0) * C0_SCALE;
-                               max_dist = tdist * tdist;
-                       }
-               }
+      if (x < minc0)
+       {
+         tdist = (x - minc0) * C0_SCALE;
+         min_dist = tdist * tdist;
+         tdist = (x - maxc0) * C0_SCALE;
+         max_dist = tdist * tdist;
+       }
+      else if (x > maxc0)
+       {
+         tdist = (x - maxc0) * C0_SCALE;
+         min_dist = tdist * tdist;
+         tdist = (x - minc0) * C0_SCALE;
+         max_dist = tdist * tdist;
+       }
+      else
+       {
+         /* within cell range so no contribution to min_dist */
+         min_dist = 0;
+         if (x <= centerc0)
+           {
+             tdist = (x - maxc0) * C0_SCALE;
+             max_dist = tdist * tdist;
+           }
+         else
+           {
+             tdist = (x - minc0) * C0_SCALE;
+             max_dist = tdist * tdist;
+           }
+       }
 
 #ifdef ORIGINAL_LIB_JPEG
-               x = GETJSAMPLE(cinfo->colormap[1][i]);
+      x = GETJSAMPLE (cinfo->colormap[1][i]);
 #else
-               x = im->green[i];
+      x = nim->green[i];
 #endif
-               if (x < minc1) {
-                       tdist = (x - minc1) * C1_SCALE;
-                       min_dist += tdist * tdist;
-                       tdist = (x - maxc1) * C1_SCALE;
-                       max_dist += tdist * tdist;
-               } else if (x > maxc1) {
-                       tdist = (x - maxc1) * C1_SCALE;
-                       min_dist += tdist * tdist;
-                       tdist = (x - minc1) * C1_SCALE;
-                       max_dist += tdist * tdist;
-               } else {
-                       /* within cell range so no contribution to min_dist */
-                       if (x <= centerc1) {
-                               tdist = (x - maxc1) * C1_SCALE;
-                               max_dist += tdist * tdist;
-                       } else {
-                               tdist = (x - minc1) * C1_SCALE;
-                               max_dist += tdist * tdist;
-                       }
-               }
+      if (x < minc1)
+       {
+         tdist = (x - minc1) * C1_SCALE;
+         min_dist += tdist * tdist;
+         tdist = (x - maxc1) * C1_SCALE;
+         max_dist += tdist * tdist;
+       }
+      else if (x > maxc1)
+       {
+         tdist = (x - maxc1) * C1_SCALE;
+         min_dist += tdist * tdist;
+         tdist = (x - minc1) * C1_SCALE;
+         max_dist += tdist * tdist;
+       }
+      else
+       {
+         /* within cell range so no contribution to min_dist */
+         if (x <= centerc1)
+           {
+             tdist = (x - maxc1) * C1_SCALE;
+             max_dist += tdist * tdist;
+           }
+         else
+           {
+             tdist = (x - minc1) * C1_SCALE;
+             max_dist += tdist * tdist;
+           }
+       }
 
 #ifdef ORIGINAL_LIB_JPEG
-               x = GETJSAMPLE (cinfo->colormap[2][i]);
+      x = GETJSAMPLE (cinfo->colormap[2][i]);
 #else
-               x = im->blue[i];
+      x = nim->blue[i];
 #endif
-               if (x < minc2) {
-                       tdist = (x - minc2) * C2_SCALE;
-                       min_dist += tdist * tdist;
-                       tdist = (x - maxc2) * C2_SCALE;
-                       max_dist += tdist * tdist;
-               } else if (x > maxc2) {
-                       tdist = (x - maxc2) * C2_SCALE;
-                       min_dist += tdist * tdist;
-                       tdist = (x - minc2) * C2_SCALE;
-                       max_dist += tdist * tdist;
-               } else {
-                       /* within cell range so no contribution to min_dist */
-                       if (x <= centerc2) {
-                               tdist = (x - maxc2) * C2_SCALE;
-                               max_dist += tdist * tdist;
-                       } else {
-                               tdist = (x - minc2) * C2_SCALE;
-                               max_dist += tdist * tdist;
-                       }
-               }
-
-               mindist[i] = min_dist;  /* save away the results */
-               if (max_dist < minmaxdist)
-               minmaxdist = max_dist;
+      if (x < minc2)
+       {
+         tdist = (x - minc2) * C2_SCALE;
+         min_dist += tdist * tdist;
+         tdist = (x - maxc2) * C2_SCALE;
+         max_dist += tdist * tdist;
        }
-
-       /* Now we know that no cell in the update box is more than minmaxdist
-        * away from some colormap entry.       Therefore, only colors that are
-        * within minmaxdist of some part of the box need be considered.
-        */
-       ncolors = 0;
-       for (i = 0; i < numcolors; i++) {
-               if (mindist[i] <= minmaxdist) {
-                       colorlist[ncolors++] = (JSAMPLE) i;
-               }
+      else if (x > maxc2)
+       {
+         tdist = (x - maxc2) * C2_SCALE;
+         min_dist += tdist * tdist;
+         tdist = (x - minc2) * C2_SCALE;
+         max_dist += tdist * tdist;
+       }
+      else
+       {
+         /* within cell range so no contribution to min_dist */
+         if (x <= centerc2)
+           {
+             tdist = (x - maxc2) * C2_SCALE;
+             max_dist += tdist * tdist;
+           }
+         else
+           {
+             tdist = (x - minc2) * C2_SCALE;
+             max_dist += tdist * tdist;
+           }
        }
-       return ncolors;
+
+      mindist[i] = min_dist;   /* save away the results */
+      if (max_dist < minmaxdist)
+       minmaxdist = max_dist;
+    }
+
+  /* Now we know that no cell in the update box is more than minmaxdist
+   * away from some colormap entry.  Therefore, only colors that are
+   * within minmaxdist of some part of the box need be considered.
+   */
+  ncolors = 0;
+  for (i = 0; i < numcolors; i++)
+    {
+      if (mindist[i] <= minmaxdist)
+       colorlist[ncolors++] = (JSAMPLE) i;
+    }
+  return ncolors;
 }
 
 
 LOCAL (void) find_best_colors (
 #ifdef ORIGINAL_LIB_JPEG
-       j_decompress_ptr cinfo,
+                               j_decompress_ptr cinfo,
 #else
-       gdImagePtr im, my_cquantize_ptr cquantize,
+                               gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize,
 #endif
-       int minc0, int minc1, int minc2,
-       int numcolors, JSAMPLE colorlist[],
-       JSAMPLE bestcolor[])
+                               int minc0, int minc1, int minc2,
+                               int numcolors, JSAMPLE colorlist[],
+                               JSAMPLE bestcolor[])
 /* Find the closest colormap entry for each cell in the update box,
  * given the list of candidate colors prepared by find_nearby_colors.
  * Return the indexes of the closest entries in the bestcolor[] array.
@@ -1059,158 +1110,169 @@ LOCAL (void) find_best_colors (
  * find the distance from a colormap entry to successive cells in the box.
  */
 {
-       int ic0, ic1, ic2;
-       int i, icolor;
-       register INT32 *bptr;           /* pointer into bestdist[] array */
-       JSAMPLE *cptr;          /* pointer into bestcolor[] array */
-       INT32 dist0, dist1;             /* initial distance values */
-       register INT32 dist2;           /* current distance in inner loop */
-       INT32 xx0, xx1;         /* distance increments */
-       register INT32 xx2;
-       INT32 inc0, inc1, inc2; /* initial values for increments */
-       /* This array holds the distance to the nearest-so-far color for each cell */
-       INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
-
-       /* Initialize best-distance for each cell of the update box */
-       bptr = bestdist;
-       for (i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--) {
-               *bptr++ = 0x7FFFFFFFL;
-       }
-
-       /* For each color selected by find_nearby_colors,
-        * compute its distance to the center of each cell in the box.
-        * If that's less than best-so-far, update best distance and color number.
-        */
-
-       /* Nominal steps between cell centers ("x" in Thomas article) */
-#define STEP_C0        ((1 << C0_SHIFT) * C0_SCALE)
-#define STEP_C1        ((1 << C1_SHIFT) * C1_SCALE)
-#define STEP_C2        ((1 << C2_SHIFT) * C2_SCALE)
-
-       for (i = 0; i < numcolors; i++) {
-               int r, g, b;
+  int ic0, ic1, ic2;
+  int i, icolor;
+  register INT32 *bptr;                /* pointer into bestdist[] array */
+  JSAMPLE *cptr;               /* pointer into bestcolor[] array */
+  INT32 dist0, dist1;          /* initial distance values */
+  register INT32 dist2;                /* current distance in inner loop */
+  INT32 xx0, xx1;              /* distance increments */
+  register INT32 xx2;
+  INT32 inc0, inc1, inc2;      /* initial values for increments */
+  /* This array holds the distance to the nearest-so-far color for each cell */
+  INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+  /* Initialize best-distance for each cell of the update box */
+  bptr = bestdist;
+  for (i = BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS - 1; i >= 0; i--)
+    *bptr++ = 0x7FFFFFFFL;
+
+  /* For each color selected by find_nearby_colors,
+   * compute its distance to the center of each cell in the box.
+   * If that's less than best-so-far, update best distance and color number.
+   */
+
+  /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_C0  ((1 << C0_SHIFT) * C0_SCALE)
+#define STEP_C1  ((1 << C1_SHIFT) * C1_SCALE)
+#define STEP_C2  ((1 << C2_SHIFT) * C2_SCALE)
+
+  for (i = 0; i < numcolors; i++)
+    {
+      int r, g, b;
 #ifdef ORIGINAL_LIB_JPEG
-               icolor = GETJSAMPLE(colorlist[i]);
-               r = GETJSAMPLE(cinfo->colormap[0][icolor]);
-               g = GETJSAMPLE(cinfo->colormap[1][icolor]);
-               b = GETJSAMPLE(cinfo->colormap[2][icolor]);
+
+      icolor = GETJSAMPLE (colorlist[i]);
+      r = GETJSAMPLE (cinfo->colormap[0][icolor]);
+      g = GETJSAMPLE (cinfo->colormap[1][icolor]);
+      b = GETJSAMPLE (cinfo->colormap[2][icolor]);
 #else
-               icolor = colorlist[i];
-               r = im->red[icolor];
-               g = im->green[icolor];
-               b = im->blue[icolor];
+      icolor = colorlist[i];
+      r = nim->red[icolor];
+      g = nim->green[icolor];
+      b = nim->blue[icolor];
 #endif
 
-               /* Compute (square of) distance from minc0/c1/c2 to this color */
-               inc0 = (minc0 - r) * C0_SCALE;
-               dist0 = inc0 * inc0;
-               inc1 = (minc1 - g) * C1_SCALE;
-               dist0 += inc1 * inc1;
-               inc2 = (minc2 - b) * C2_SCALE;
-               dist0 += inc2 * inc2;
-               /* Form the initial difference increments */
-               inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
-               inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
-               inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
-               /* Now loop over all cells in box, updating distance per Thomas method */
-               bptr = bestdist;
-               cptr = bestcolor;
-               xx0 = inc0;
-               for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--) {
-                       dist1 = dist0;
-                       xx1 = inc1;
-                       for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--) {
-                               dist2 = dist1;
-                               xx2 = inc2;
-                               for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) {
-                                       if (dist2 < *bptr) {
-                                               *bptr = dist2;
-                                               *cptr = (JSAMPLE) icolor;
-                                       }
-                                       dist2 += xx2;
-                                       xx2 += 2 * STEP_C2 * STEP_C2;
-                                       bptr++;
-                                       cptr++;
-                               }
-                               dist1 += xx1;
-                               xx1 += 2 * STEP_C1 * STEP_C1;
-                       }
-                       dist0 += xx0;
-                       xx0 += 2 * STEP_C0 * STEP_C0;
+      /* Compute (square of) distance from minc0/c1/c2 to this color */
+      inc0 = (minc0 - r) * C0_SCALE;
+      dist0 = inc0 * inc0;
+      inc1 = (minc1 - g) * C1_SCALE;
+      dist0 += inc1 * inc1;
+      inc2 = (minc2 - b) * C2_SCALE;
+      dist0 += inc2 * inc2;
+      /* Form the initial difference increments */
+      inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
+      inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
+      inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
+      /* Now loop over all cells in box, updating distance per Thomas method */
+      bptr = bestdist;
+      cptr = bestcolor;
+      xx0 = inc0;
+      for (ic0 = BOX_C0_ELEMS - 1; ic0 >= 0; ic0--)
+       {
+         dist1 = dist0;
+         xx1 = inc1;
+         for (ic1 = BOX_C1_ELEMS - 1; ic1 >= 0; ic1--)
+           {
+             dist2 = dist1;
+             xx2 = inc2;
+             for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--)
+               {
+                 if (dist2 < *bptr)
+                   {
+                     *bptr = dist2;
+                     *cptr = (JSAMPLE) icolor;
+                   }
+                 dist2 += xx2;
+                 xx2 += 2 * STEP_C2 * STEP_C2;
+                 bptr++;
+                 cptr++;
                }
+             dist1 += xx1;
+             xx1 += 2 * STEP_C1 * STEP_C1;
+           }
+         dist0 += xx0;
+         xx0 += 2 * STEP_C0 * STEP_C0;
        }
+    }
 }
 
 
 LOCAL (void)
 fill_inverse_cmap (
 #ifdef ORIGINAL_LIB_JPEG
-       j_decompress_ptr cinfo,
+                   j_decompress_ptr cinfo,
 #else
-       gdImagePtr im, my_cquantize_ptr cquantize,
+                   gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize,
 #endif
-       int c0, int c1, int c2)
+                   int c0, int c1, int c2)
 /* Fill the inverse-colormap entries in the update box that contains */
-/* histogram cell c0/c1/c2.    (Only that one cell MUST be filled, but */
+/* histogram cell c0/c1/c2.  (Only that one cell MUST be filled, but */
 /* we can fill as many others as we wish.) */
 {
 #ifdef ORIGINAL_LIB_JPEG
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 #endif
-       hist3d histogram = cquantize->histogram;
-       int minc0, minc1, minc2;        /* lower left corner of update box */
-       int ic0, ic1, ic2;
-       register JSAMPLE *cptr; /* pointer into bestcolor[] array */
-       register histptr cachep;        /* pointer into main cache array */
-       /* This array lists the candidate colormap indexes. */
-       JSAMPLE colorlist[MAXNUMCOLORS];
-       int numcolors;          /* number of candidate colors */
-       /* This array holds the actually closest colormap index for each cell. */
-       JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
-
-       /* Convert cell coordinates to update box ID */
-       c0 >>= BOX_C0_LOG;
-       c1 >>= BOX_C1_LOG;
-       c2 >>= BOX_C2_LOG;
-
-       /* Compute true coordinates of update box's origin corner.
-        * Actually we compute the coordinates of the center of the corner
-        * histogram cell, which are the lower bounds of the volume we care about.
-        */
-       minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
-       minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
-       minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
-
-       /* Determine which colormap entries are close enough to be candidates
-        * for the nearest entry to some cell in the update box.
-        */
+  hist3d histogram = cquantize->histogram;
+  int minc0, minc1, minc2;     /* lower left corner of update box */
+  int ic0, ic1, ic2;
+  register JSAMPLE *cptr;      /* pointer into bestcolor[] array */
+  register histptr cachep;     /* pointer into main cache array */
+  /* This array lists the candidate colormap indexes. */
+  JSAMPLE colorlist[MAXNUMCOLORS];
+  int numcolors;               /* number of candidate colors */
+  /* This array holds the actually closest colormap index for each cell. */
+  JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+  /* Convert cell coordinates to update box ID */
+  c0 >>= BOX_C0_LOG;
+  c1 >>= BOX_C1_LOG;
+  c2 >>= BOX_C2_LOG;
+
+  /* Compute true coordinates of update box's origin corner.
+   * Actually we compute the coordinates of the center of the corner
+   * histogram cell, which are the lower bounds of the volume we care about.
+   */
+  minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
+  minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
+  minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
+
+  /* Determine which colormap entries are close enough to be candidates
+   * for the nearest entry to some cell in the update box.
+   */
 #ifdef ORIGINAL_LIB_JPEG
-       numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
+  numcolors = find_nearby_colors (cinfo, minc0, minc1, minc2, colorlist);
 
-       /* Determine the actually nearest colors. */
-       find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, bestcolor);
+  /* Determine the actually nearest colors. */
+  find_best_colors (cinfo, minc0, minc1, minc2, numcolors, colorlist,
+                   bestcolor);
 #else
-       numcolors = find_nearby_colors(im, cquantize, minc0, minc1, minc2, colorlist);
-       find_best_colors(im, cquantize, minc0, minc1, minc2, numcolors, colorlist, bestcolor);
+  numcolors =
+    find_nearby_colors (oim, nim, cquantize, minc0, minc1, minc2, colorlist);
+  find_best_colors (oim, nim, cquantize, minc0, minc1, minc2, numcolors,
+                   colorlist, bestcolor);
 #endif
 
-       /* Save the best color numbers (plus 1) in the main cache array */
-       c0 <<= BOX_C0_LOG;              /* convert ID back to base cell indexes */
-       c1 <<= BOX_C1_LOG;
-       c2 <<= BOX_C2_LOG;
-       cptr = bestcolor;
-       for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
-               for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
-                       cachep = &histogram[c0 + ic0][c1 + ic1][c2];
-                       for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
+  /* Save the best color numbers (plus 1) in the main cache array */
+  c0 <<= BOX_C0_LOG;           /* convert ID back to base cell indexes */
+  c1 <<= BOX_C1_LOG;
+  c2 <<= BOX_C2_LOG;
+  cptr = bestcolor;
+  for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++)
+    {
+      for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++)
+       {
+         cachep = &histogram[c0 + ic0][c1 + ic1][c2];
+         for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++)
+           {
 #ifdef ORIGINAL_LIB_JPEG
-                               *cachep++ = (histcell) (GETJSAMPLE (*cptr++) + 1);
+             *cachep++ = (histcell) (GETJSAMPLE (*cptr++) + 1);
 #else
-                               *cachep++ = (histcell) ((*cptr++) + 1);
+             *cachep++ = (histcell) ((*cptr++) + 1);
 #endif
-                       }
-               }
+           }
        }
+    }
 }
 
 
@@ -1220,287 +1282,304 @@ fill_inverse_cmap (
 
 METHODDEF (void)
 #ifndef ORIGINAL_LIB_JPEG
-pass2_no_dither (gdImagePtr im, my_cquantize_ptr cquantize)
+pass2_no_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
 {
-       register int *inptr;
-       register unsigned char *outptr;
-       int width = im->sx;
-       int num_rows = im->sy;
+  register int *inptr;
+  register unsigned char *outptr;
+  int width = oim->sx;
+  int num_rows = oim->sy;
 #else
-pass2_no_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+pass2_no_dither (j_decompress_ptr cinfo,
+                JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
 /* This version performs no dithering */
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
-       register JSAMPROW inptr, outptr;
-       JDIMENSION width = cinfo->output_width;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  register JSAMPROW inptr, outptr;
+  JDIMENSION width = cinfo->output_width;
 #endif
-       hist3d histogram = cquantize->histogram;
-       register int c0, c1, c2;
-       int row;
-       JDIMENSION col;
-       register histptr cachep;
-
-
-       for (row = 0; row < num_rows; row++) {
-               inptr = input_buf[row];
-               outptr = output_buf[row];
-               for (col = width; col > 0; col--){
-                       /* get pixel value and index into the cache */
-                       int r, g, b;
+  hist3d histogram = cquantize->histogram;
+  register int c0, c1, c2;
+  int row;
+  JDIMENSION col;
+  register histptr cachep;
+
+
+  for (row = 0; row < num_rows; row++)
+    {
+      inptr = input_buf[row];
+      outptr = output_buf[row];
+      for (col = width; col > 0; col--)
+       {
+         /* get pixel value and index into the cache */
+         int r, g, b;
 #ifdef ORIGINAL_LIB_JPEG
-                       r = GETJSAMPLE(*inptr++);
-                       g = GETJSAMPLE(*inptr++);
-                       b = GETJSAMPLE(*inptr++);
+         r = GETJSAMPLE (*inptr++);
+         g = GETJSAMPLE (*inptr++);
+         b = GETJSAMPLE (*inptr++);
 #else
-                       r = gdTrueColorGetRed(*inptr);
-                       g = gdTrueColorGetGreen(*inptr);
-                       b = gdTrueColorGetBlue(*inptr++);
-
-                       /* If the pixel is transparent, we assign it the palette index that
-                        * will later be added at the end of the palette as the transparent
-                        * index.
-                        */
-                       if ((im->transparent >= 0) && (im->transparent == *(inptr - 1))) {
-                               *outptr++ = im->colorsTotal;
-                               continue;
-                       }
+         r = gdTrueColorGetRed (*inptr);
+         g = gdTrueColorGetGreen (*inptr);
+         /* 
+            2.0.24: inptr must not be incremented until after
+            transparency check, if any. Thanks to "Super Pikeman." 
+          */
+         b = gdTrueColorGetBlue (*inptr);
+
+         /* If the pixel is transparent, we assign it the palette index that
+          * will later be added at the end of the palette as the transparent
+          * index. */
+         if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1)))
+           {
+             *outptr++ = nim->colorsTotal;
+             inptr++;
+             continue;
+           }
+         inptr++;
 #endif
-                       c0 = r >> C0_SHIFT;
-                       c1 = g >> C1_SHIFT;
-                       c2 = b >> C2_SHIFT;
-                       cachep = &histogram[c0][c1][c2];
-                       /* If we have not seen this color before, find nearest colormap entry
-                        * and update the cache
-                        */
-                       if (*cachep == 0) {
+         c0 = r >> C0_SHIFT;
+         c1 = g >> C1_SHIFT;
+         c2 = b >> C2_SHIFT;
+         cachep = &histogram[c0][c1][c2];
+         /* If we have not seen this color before, find nearest colormap entry */
+         /* and update the cache */
+         if (*cachep == 0)
 #ifdef ORIGINAL_LIB_JPEG
-                               fill_inverse_cmap(cinfo, c0, c1, c2);
+           fill_inverse_cmap (cinfo, c0, c1, c2);
 #else
-                               fill_inverse_cmap(im, cquantize, c0, c1, c2);
+           fill_inverse_cmap (oim, nim, cquantize, c0, c1, c2);
 #endif
-                       }
-                       /* Now emit the colormap index for this cell */
+         /* Now emit the colormap index for this cell */
 #ifdef ORIGINAL_LIB_JPEG
-                       *outptr++ = (JSAMPLE) (*cachep - 1);
+         *outptr++ = (JSAMPLE) (*cachep - 1);
 #else
-                       *outptr++ = (*cachep - 1);
+         *outptr++ = (*cachep - 1);
 #endif
-               }
        }
+    }
 }
 
 
 METHODDEF (void)
 #ifndef ORIGINAL_LIB_JPEG
-pass2_fs_dither (gdImagePtr im, my_cquantize_ptr cquantize)
+pass2_fs_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
 {
 #else
-pass2_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+pass2_fs_dither (j_decompress_ptr cinfo,
+                JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
 /* This version performs Floyd-Steinberg dithering */
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
-       JSAMPROW inptr;         /* => current input pixel */
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  JSAMPROW inptr;              /* => current input pixel */
 #endif
-       hist3d histogram = cquantize->histogram;
-       register LOCFSERROR cur0, cur1, cur2;   /* current error or pixel value */
-       LOCFSERROR belowerr0, belowerr1, belowerr2;     /* error for pixel below cur */
-       LOCFSERROR bpreverr0, bpreverr1, bpreverr2;     /* error for below/prev col */
-       register FSERRPTR errorptr;     /* => fserrors[] at column before current */
-       histptr cachep;
-       int dir;                        /* +1 or -1 depending on direction */
-       int dir3;                       /* 3*dir, for advancing inptr & errorptr */
-       int row;
-       JDIMENSION col;
+  hist3d histogram = cquantize->histogram;
+  register LOCFSERROR cur0, cur1, cur2;        /* current error or pixel value */
+  LOCFSERROR belowerr0, belowerr1, belowerr2;  /* error for pixel below cur */
+  LOCFSERROR bpreverr0, bpreverr1, bpreverr2;  /* error for below/prev col */
+  register FSERRPTR errorptr;  /* => fserrors[] at column before current */
+  histptr cachep;
+  int dir;                     /* +1 or -1 depending on direction */
+  int dir3;                    /* 3*dir, for advancing inptr & errorptr */
+  int row;
+  JDIMENSION col;
 #ifdef ORIGINAL_LIB_JPEG
-       JSAMPROW outptr;                /* => current output pixel */
-       JDIMENSION width = cinfo->output_width;
-       JSAMPLE *range_limit = cinfo->sample_range_limit;
-       JSAMPROW colormap0 = cinfo->colormap[0];
-       JSAMPROW colormap1 = cinfo->colormap[1];
-       JSAMPROW colormap2 = cinfo->colormap[2];
+  JSAMPROW outptr;             /* => current output pixel */
+  JDIMENSION width = cinfo->output_width;
+  JSAMPLE *range_limit = cinfo->sample_range_limit;
+  JSAMPROW colormap0 = cinfo->colormap[0];
+  JSAMPROW colormap1 = cinfo->colormap[1];
+  JSAMPROW colormap2 = cinfo->colormap[2];
 #else
-       int *inptr;                     /* => current input pixel */
-       unsigned char *outptr;  /* => current output pixel */
-       int width = im->sx;
-       int num_rows = im->sy;
-       int *colormap0 = im->red;
-       int *colormap1 = im->green;
-       int *colormap2 = im->blue;
+  int *inptr;                  /* => current input pixel */
+  unsigned char *outptr;       /* => current output pixel */
+  int width = oim->sx;
+  int num_rows = oim->sy;
+  int *colormap0 = nim->red;
+  int *colormap1 = nim->green;
+  int *colormap2 = nim->blue;
 #endif
-       int *error_limit = cquantize->error_limiter;
-
-
-       SHIFT_TEMPS for (row = 0; row < num_rows; row++) {
-               inptr = input_buf[row];
-               outptr = output_buf[row];
-               if (cquantize->on_odd_row) {
-                       /* work right to left in this row */
-                       inptr += (width - 1) * 3;       /* so point to rightmost pixel */
-                       outptr += width - 1;
-                       dir = -1;
-                       dir3 = -3;
-                       errorptr = cquantize->fserrors + (width + 1) * 3;       /* => entry after last column */
+  int *error_limit = cquantize->error_limiter;
+
+
+  SHIFT_TEMPS for (row = 0; row < num_rows; row++)
+    {
+      inptr = input_buf[row];
+      outptr = output_buf[row];
+      if (cquantize->on_odd_row)
+       {
+         /* work right to left in this row */
+         inptr += (width - 1) * 3;     /* so point to rightmost pixel */
+         outptr += width - 1;
+         dir = -1;
+         dir3 = -3;
+         errorptr = cquantize->fserrors + (width + 1) * 3;     /* => entry after last column */
 #ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS
-                       cquantize->on_odd_row = FALSE;  /* flip for next time */
+         cquantize->on_odd_row = FALSE;        /* flip for next time */
 #endif
-               } else {
-                       /* work left to right in this row */
-                       dir = 1;
-                       dir3 = 3;
-                       errorptr = cquantize->fserrors; /* => entry before first real column */
+       }
+      else
+       {
+         /* work left to right in this row */
+         dir = 1;
+         dir3 = 3;
+         errorptr = cquantize->fserrors;       /* => entry before first real column */
 #ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS
-                       cquantize->on_odd_row = TRUE;   /* flip for next time */
+         cquantize->on_odd_row = TRUE; /* flip for next time */
 #endif
-               }
-               /* Preset error values: no error propagated to first pixel from left */
-               cur0 = cur1 = cur2 = 0;
-               /* and no error propagated to row below yet */
-               belowerr0 = belowerr1 = belowerr2 = 0;
-               bpreverr0 = bpreverr1 = bpreverr2 = 0;
-
-               for (col = width; col > 0; col--) {
-                       /* If this pixel is transparent, we want to assign it to the special
-                        * transparency color index past the end of the palette rather than
-                        * go through matching / dithering. */
-                       if ((im->transparent >= 0) && (*inptr == im->transparent)) {
-                               *outptr = im->colorsTotal;
-                               errorptr[0] = 0;
-                               errorptr[1] = 0;
-                               errorptr[2] = 0;
-                               errorptr[3] = 0;
-                               inptr += dir;
-                               outptr += dir;
-                               errorptr += dir3;
-                               continue;
-                       }
-                       /* curN holds the error propagated from the previous pixel on the
-                        * current line.        Add the error propagated from the previous line
-                        * to form the complete error correction term for this pixel, and
-                        * round the error term (which is expressed * 16) to an integer.
-                        * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
-                        * for either sign of the error value.
-                        * Note: errorptr points to *previous* column's array entry.
-                        */
-                       cur0 = RIGHT_SHIFT (cur0 + errorptr[dir3 + 0] + 8, 4);
-                       cur1 = RIGHT_SHIFT (cur1 + errorptr[dir3 + 1] + 8, 4);
-                       cur2 = RIGHT_SHIFT (cur2 + errorptr[dir3 + 2] + 8, 4);
-                       /* Limit the error using transfer function set by init_error_limit.
-                        * See comments with init_error_limit for rationale.
-                        */
-                       cur0 = error_limit[cur0];
-                       cur1 = error_limit[cur1];
-                       cur2 = error_limit[cur2];
-                       /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
-                        * The maximum error is +- MAXJSAMPLE (or less with error limiting);
-                        * this sets the required size of the range_limit array.
-                        */
+       }
+      /* Preset error values: no error propagated to first pixel from left */
+      cur0 = cur1 = cur2 = 0;
+      /* and no error propagated to row below yet */
+      belowerr0 = belowerr1 = belowerr2 = 0;
+      bpreverr0 = bpreverr1 = bpreverr2 = 0;
+
+      for (col = width; col > 0; col--)
+       {
+
+         /* If this pixel is transparent, we want to assign it to the special
+          * transparency color index past the end of the palette rather than
+          * go through matching / dithering. */
+         if ((oim->transparent >= 0) && (*inptr == oim->transparent))
+           {
+             *outptr = nim->colorsTotal;
+             errorptr[0] = 0;
+             errorptr[1] = 0;
+             errorptr[2] = 0;
+             errorptr[3] = 0;
+             inptr += dir;
+             outptr += dir;
+             errorptr += dir3;
+             continue;
+           }
+         /* curN holds the error propagated from the previous pixel on the
+          * current line.  Add the error propagated from the previous line
+          * to form the complete error correction term for this pixel, and
+          * round the error term (which is expressed * 16) to an integer.
+          * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+          * for either sign of the error value.
+          * Note: errorptr points to *previous* column's array entry.
+          */
+         cur0 = RIGHT_SHIFT (cur0 + errorptr[dir3 + 0] + 8, 4);
+         cur1 = RIGHT_SHIFT (cur1 + errorptr[dir3 + 1] + 8, 4);
+         cur2 = RIGHT_SHIFT (cur2 + errorptr[dir3 + 2] + 8, 4);
+         /* Limit the error using transfer function set by init_error_limit.
+          * See comments with init_error_limit for rationale.
+          */
+         cur0 = error_limit[cur0];
+         cur1 = error_limit[cur1];
+         cur2 = error_limit[cur2];
+         /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+          * The maximum error is +- MAXJSAMPLE (or less with error limiting);
+          * this sets the required size of the range_limit array.
+          */
 #ifdef ORIGINAL_LIB_JPEG
-                       cur0 += GETJSAMPLE (inptr[0]);
-                       cur1 += GETJSAMPLE (inptr[1]);
-                       cur2 += GETJSAMPLE (inptr[2]);
-                       cur0 = GETJSAMPLE (range_limit[cur0]);
-                       cur1 = GETJSAMPLE (range_limit[cur1]);
-                       cur2 = GETJSAMPLE (range_limit[cur2]);
+         cur0 += GETJSAMPLE (inptr[0]);
+         cur1 += GETJSAMPLE (inptr[1]);
+         cur2 += GETJSAMPLE (inptr[2]);
+         cur0 = GETJSAMPLE (range_limit[cur0]);
+         cur1 = GETJSAMPLE (range_limit[cur1]);
+         cur2 = GETJSAMPLE (range_limit[cur2]);
 #else
-                       cur0 += gdTrueColorGetRed (*inptr);
-                       cur1 += gdTrueColorGetGreen (*inptr);
-                       cur2 += gdTrueColorGetBlue (*inptr);
-                       range_limit (cur0);
-                       range_limit (cur1);
-                       range_limit (cur2);
+         cur0 += gdTrueColorGetRed (*inptr);
+         cur1 += gdTrueColorGetGreen (*inptr);
+         cur2 += gdTrueColorGetBlue (*inptr);
+         range_limit (cur0);
+         range_limit (cur1);
+         range_limit (cur2);
 #endif
 
-                       /* Index into the cache with adjusted pixel value */
-                       cachep = &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT];
-                       /* If we have not seen this color before, find nearest colormap */
-                       /* entry and update the cache */
-                       if (*cachep == 0) {
+         /* Index into the cache with adjusted pixel value */
+         cachep =
+           &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT];
+         /* If we have not seen this color before, find nearest colormap */
+         /* entry and update the cache */
+         if (*cachep == 0)
 #ifdef ORIGINAL_LIB_JPEG
-                               fill_inverse_cmap(cinfo, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);
+           fill_inverse_cmap (cinfo, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT,
+                              cur2 >> C2_SHIFT);
 #else
-                               fill_inverse_cmap(im, cquantize, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);
+           fill_inverse_cmap (oim, nim, cquantize, cur0 >> C0_SHIFT,
+                              cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);
 #endif
-                       }
-                       /* Now emit the colormap index for this cell */
-                       {
-                               register int pixcode = *cachep - 1;
-                               *outptr = (JSAMPLE) pixcode;
-                               /* Compute representation error for this pixel */
+         /* Now emit the colormap index for this cell */
+         {
+           register int pixcode = *cachep - 1;
+           *outptr = (JSAMPLE) pixcode;
+           /* Compute representation error for this pixel */
 #define GETJSAMPLE
-                               cur0 -= GETJSAMPLE(colormap0[pixcode]);
-                               cur1 -= GETJSAMPLE(colormap1[pixcode]);
-                               cur2 -= GETJSAMPLE(colormap2[pixcode]);
+           cur0 -= GETJSAMPLE (colormap0[pixcode]);
+           cur1 -= GETJSAMPLE (colormap1[pixcode]);
+           cur2 -= GETJSAMPLE (colormap2[pixcode]);
 #undef GETJSAMPLE
-                       }
-                       /* Compute error fractions to be propagated to adjacent pixels.
-                        * Add these into the running sums, and simultaneously shift the
-                        * next-line error sums left by 1 column.
-                        */
-                       {
-                               register LOCFSERROR bnexterr, delta;
-
-                               bnexterr = cur0;        /* Process component 0 */
-                               delta = cur0 * 2;
-                               cur0 += delta;  /* form error * 3 */
-                               errorptr[0] = (FSERROR) (bpreverr0 + cur0);
-                               cur0 += delta;  /* form error * 5 */
-                               bpreverr0 = belowerr0 + cur0;
-                               belowerr0 = bnexterr;
-                               cur0 += delta;  /* form error * 7 */
-                               bnexterr = cur1;        /* Process component 1 */
-                               delta = cur1 * 2;
-                               cur1 += delta;  /* form error * 3 */
-                               errorptr[1] = (FSERROR) (bpreverr1 + cur1);
-                               cur1 += delta;  /* form error * 5 */
-                               bpreverr1 = belowerr1 + cur1;
-                               belowerr1 = bnexterr;
-                               cur1 += delta;  /* form error * 7 */
-                               bnexterr = cur2;        /* Process component 2 */
-                               delta = cur2 * 2;
-                               cur2 += delta;  /* form error * 3 */
-                               errorptr[2] = (FSERROR) (bpreverr2 + cur2);
-                               cur2 += delta;  /* form error * 5 */
-                               bpreverr2 = belowerr2 + cur2;
-                               belowerr2 = bnexterr;
-                               cur2 += delta;  /* form error * 7 */
-                       }
-                       /* At this point curN contains the 7/16 error value to be propagated
-                        * to the next pixel on the current line, and all the errors for the
-                        * next line have been shifted over.    We are therefore ready to move on.
-                        */
+         }
+         /* Compute error fractions to be propagated to adjacent pixels.
+          * Add these into the running sums, and simultaneously shift the
+          * next-line error sums left by 1 column.
+          */
+         {
+           register LOCFSERROR bnexterr, delta;
+
+           bnexterr = cur0;    /* Process component 0 */
+           delta = cur0 * 2;
+           cur0 += delta;      /* form error * 3 */
+           errorptr[0] = (FSERROR) (bpreverr0 + cur0);
+           cur0 += delta;      /* form error * 5 */
+           bpreverr0 = belowerr0 + cur0;
+           belowerr0 = bnexterr;
+           cur0 += delta;      /* form error * 7 */
+           bnexterr = cur1;    /* Process component 1 */
+           delta = cur1 * 2;
+           cur1 += delta;      /* form error * 3 */
+           errorptr[1] = (FSERROR) (bpreverr1 + cur1);
+           cur1 += delta;      /* form error * 5 */
+           bpreverr1 = belowerr1 + cur1;
+           belowerr1 = bnexterr;
+           cur1 += delta;      /* form error * 7 */
+           bnexterr = cur2;    /* Process component 2 */
+           delta = cur2 * 2;
+           cur2 += delta;      /* form error * 3 */
+           errorptr[2] = (FSERROR) (bpreverr2 + cur2);
+           cur2 += delta;      /* form error * 5 */
+           bpreverr2 = belowerr2 + cur2;
+           belowerr2 = bnexterr;
+           cur2 += delta;      /* form error * 7 */
+         }
+         /* At this point curN contains the 7/16 error value to be propagated
+          * to the next pixel on the current line, and all the errors for the
+          * next line have been shifted over.  We are therefore ready to move on.
+          */
 #ifdef ORIGINAL_LIB_JPEG
-                       inptr += dir3;  /* Advance pixel pointers to next column */
+         inptr += dir3;        /* Advance pixel pointers to next column */
 #else
-                       inptr += dir;           /* Advance pixel pointers to next column */
+         inptr += dir;         /* Advance pixel pointers to next column */
 #endif
-                       outptr += dir;
-                       errorptr += dir3;       /* advance errorptr to current column */
-               }
-               /* Post-loop cleanup: we must unload the final error values into the
-                * final fserrors[] entry.      Note we need not unload belowerrN because
-                * it is for the dummy column before or after the actual array.
-                */
-               errorptr[0] = (FSERROR) bpreverr0;      /* unload prev errs into array */
-               errorptr[1] = (FSERROR) bpreverr1;
-               errorptr[2] = (FSERROR) bpreverr2;
+         outptr += dir;
+         errorptr += dir3;     /* advance errorptr to current column */
        }
+      /* Post-loop cleanup: we must unload the final error values into the
+       * final fserrors[] entry.  Note we need not unload belowerrN because
+       * it is for the dummy column before or after the actual array.
+       */
+      errorptr[0] = (FSERROR) bpreverr0;       /* unload prev errs into array */
+      errorptr[1] = (FSERROR) bpreverr1;
+      errorptr[2] = (FSERROR) bpreverr2;
+    }
 }
 
 
 /*
  * Initialize the error-limiting transfer function (lookup table).
  * The raw F-S error computation can potentially compute error values of up to
- * +- MAXJSAMPLE.      But we want the maximum correction applied to a pixel to be
- * much less, otherwise obviously wrong pixels will be created.        (Typical
+ * +- MAXJSAMPLE.  But we want the maximum correction applied to a pixel to be
+ * much less, otherwise obviously wrong pixels will be created.  (Typical
  * effects include weird fringes at color-area boundaries, isolated bright
- * pixels in a dark area, etc.)        The standard advice for avoiding this problem
+ * pixels in a dark area, etc.)  The standard advice for avoiding this problem
  * is to ensure that the "corners" of the color cube are allocated as output
  * colors; then repeated errors in the same direction cannot cause cascading
- * error buildup.      However, that only prevents the error from getting
+ * error buildup.  However, that only prevents the error from getting
  * completely out of hand; Aaron Giles reports that error limiting improves
  * the results even with corner colors allocated.
  * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
- * well, but the smoother transfer function used below is even better. Thanks
+ * well, but the smoother transfer function used below is even better.  Thanks
  * to Aaron Giles for this idea.
  */
 
@@ -1508,43 +1587,49 @@ LOCAL (void)
 #ifdef ORIGINAL_LIB_JPEG
 init_error_limit (j_decompress_ptr cinfo)
 #else
-init_error_limit (gdImagePtr im, my_cquantize_ptr cquantize)
+init_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)
 #endif
 /* Allocate and fill in the error_limiter table */
 {
-       int *table;
-       int in, out;
+  int *table;
+  int in, out;
 #ifdef ORIGINAL_LIB_JPEG
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
-       table = (int *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * SIZEOF (int));
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  table = (int *) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * SIZEOF (int));
 #else
-       cquantize->error_limiter_storage = (int *) safe_emalloc((MAXJSAMPLE * 2 + 1), sizeof(int), 0);
-       if (!cquantize->error_limiter_storage) {
-               return;
-       }
-       table = cquantize->error_limiter_storage;
+  cquantize->error_limiter_storage =
+    (int *) safe_emalloc ((MAXJSAMPLE * 2 + 1), sizeof (int), 0);
+  if (!cquantize->error_limiter_storage)
+    {
+      return;
+    }
+  table = cquantize->error_limiter_storage;
 #endif
 
-       table += MAXJSAMPLE;            /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
-       cquantize->error_limiter = table;
+  table += MAXJSAMPLE;         /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
+  cquantize->error_limiter = table;
 
 #define STEPSIZE ((MAXJSAMPLE+1)/16)
-       /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
-       out = 0;
-       for (in = 0; in < STEPSIZE; in++, out++){
-               table[in] = out;
-               table[-in] = -out;
-       }
-       /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
-       for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) {
-               table[in] = out;
-               table[-in] = -out;
-       }
-       /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
-       for (; in <= MAXJSAMPLE; in++) {
-               table[in] = out;
-               table[-in] = -out;
-       }
+  /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
+  out = 0;
+  for (in = 0; in < STEPSIZE; in++, out++)
+    {
+      table[in] = out;
+      table[-in] = -out;
+    }
+  /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
+  for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1)
+    {
+      table[in] = out;
+      table[-in] = -out;
+    }
+  /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
+  for (; in <= MAXJSAMPLE; in++)
+    {
+      table[in] = out;
+      table[-in] = -out;
+    }
 #undef STEPSIZE
 }
 
@@ -1554,85 +1639,91 @@ init_error_limit (gdImagePtr im, my_cquantize_ptr cquantize)
  */
 
 #ifdef ORIGINAL_LIB_JPEG
-METHODDEF (void) finish_pass1 (j_decompress_ptr cinfo)
+METHODDEF (void)
+finish_pass1 (j_decompress_ptr cinfo)
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 
-       /* Select the representative colors and fill in cinfo->colormap */
-       cinfo->colormap = cquantize->sv_colormap;
-       select_colors (cinfo, cquantize->desired);
-       /* Force next pass to zero the color index table */
-       cquantize->needs_zeroed = TRUE;
+  /* Select the representative colors and fill in cinfo->colormap */
+  cinfo->colormap = cquantize->sv_colormap;
+  select_colors (cinfo, cquantize->desired);
+  /* Force next pass to zero the color index table */
+  cquantize->needs_zeroed = TRUE;
 }
 
 
-METHODDEF (void) finish_pass2 (j_decompress_ptr cinfo)
+METHODDEF (void)
+finish_pass2 (j_decompress_ptr cinfo)
 {
-       /* no work */
+  /* no work */
 }
 
 /*
  * Initialize for each processing pass.
  */
 
-METHODDEF (void) start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+METHODDEF (void)
+start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
-       hist3d histogram = cquantize->histogram;
-       int i;
-
-       /* Only F-S dithering or no dithering is supported. */
-       /* If user asks for ordered dither, give him F-S. */
-       if (cinfo->dither_mode != JDITHER_NONE) {
-               cinfo->dither_mode = JDITHER_FS;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  hist3d histogram = cquantize->histogram;
+  int i;
+
+  /* Only F-S dithering or no dithering is supported. */
+  /* If user asks for ordered dither, give him F-S. */
+  if (cinfo->dither_mode != JDITHER_NONE)
+    cinfo->dither_mode = JDITHER_FS;
+
+  if (is_pre_scan)
+    {
+      /* Set up method pointers */
+      cquantize->pub.color_quantize = prescan_quantize;
+      cquantize->pub.finish_pass = finish_pass1;
+      cquantize->needs_zeroed = TRUE;  /* Always zero histogram */
+    }
+  else
+    {
+      /* Set up method pointers */
+      if (cinfo->dither_mode == JDITHER_FS)
+       cquantize->pub.color_quantize = pass2_fs_dither;
+      else
+       cquantize->pub.color_quantize = pass2_no_dither;
+      cquantize->pub.finish_pass = finish_pass2;
+
+      /* Make sure color count is acceptable */
+      i = cinfo->actual_number_of_colors;
+      if (i < 1)
+       ERREXIT1 (cinfo, JERR_QUANT_FEW_COLORS, 1);
+      if (i > MAXNUMCOLORS)
+       ERREXIT1 (cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+
+      if (cinfo->dither_mode == JDITHER_FS)
+       {
+         size_t arraysize = (size_t) ((cinfo->output_width + 2) *
+                                      (3 * SIZEOF (FSERROR)));
+         /* Allocate Floyd-Steinberg workspace if we didn't already. */
+         if (cquantize->fserrors == NULL)
+           cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+             ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+         /* Initialize the propagated errors to zero. */
+         jzero_far ((void FAR *) cquantize->fserrors, arraysize);
+         /* Make the error-limit table if we didn't already. */
+         if (cquantize->error_limiter == NULL)
+           init_error_limit (cinfo);
+         cquantize->on_odd_row = FALSE;
        }
 
-       if (is_pre_scan){
-               /* Set up method pointers */
-               cquantize->pub.color_quantize = prescan_quantize;
-               cquantize->pub.finish_pass = finish_pass1;
-               cquantize->needs_zeroed = TRUE; /* Always zero histogram */
-       } else {
-               /* Set up method pointers */
-               if (cinfo->dither_mode == JDITHER_FS) {
-                       cquantize->pub.color_quantize = pass2_fs_dither;
-               } else {
-                       cquantize->pub.color_quantize = pass2_no_dither;
-               }
-               cquantize->pub.finish_pass = finish_pass2;
-
-               /* Make sure color count is acceptable */
-               i = cinfo->actual_number_of_colors;
-               if (i < 1) {
-                       ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1);
-               }
-               if (i > MAXNUMCOLORS) {
-                       ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
-               }
-
-               if (cinfo->dither_mode == JDITHER_FS) {
-                       size_t arraysize = (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF (FSERROR)));
-                       /* Allocate Floyd-Steinberg workspace if we didn't already. */
-                       if (cquantize->fserrors == NULL) {
-                               cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
-                       }
-                       /* Initialize the propagated errors to zero. */
-                       jzero_far((void FAR *) cquantize->fserrors, arraysize);
-                       /* Make the error-limit table if we didn't already. */
-                       if (cquantize->error_limiter == NULL) {
-                               init_error_limit(cinfo);
-                       }
-                       cquantize->on_odd_row = FALSE;
-               }
-
-       }
-       /* Zero the histogram or inverse color map, if necessary */
-       if (cquantize->needs_zeroed) {
-               for (i = 0; i < HIST_C0_ELEMS; i++) {
-                       jzero_far((void FAR *) histogram[i], HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell));
-               }
-               cquantize->needs_zeroed = FALSE;
+    }
+  /* Zero the histogram or inverse color map, if necessary */
+  if (cquantize->needs_zeroed)
+    {
+      for (i = 0; i < HIST_C0_ELEMS; i++)
+       {
+         jzero_far ((void FAR *) histogram[i],
+                    HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell));
        }
+      cquantize->needs_zeroed = FALSE;
+    }
 }
 
 
@@ -1640,24 +1731,42 @@ METHODDEF (void) start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan
  * Switch to a new external colormap between output passes.
  */
 
-METHODDEF (void) new_color_map_2_quant (j_decompress_ptr cinfo)
+METHODDEF (void)
+new_color_map_2_quant (j_decompress_ptr cinfo)
 {
-       my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+  my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
 
-       /* Reset the inverse color map */
-       cquantize->needs_zeroed = TRUE;
+  /* Reset the inverse color map */
+  cquantize->needs_zeroed = TRUE;
 }
 #else
-static void zeroHistogram (hist3d histogram)
+static void
+zeroHistogram (hist3d histogram)
 {
-       int i;
-       /* Zero the histogram or inverse color map */
-       for (i = 0; i < HIST_C0_ELEMS; i++) {
-               memset (histogram[i], 0, HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof (histcell));
-       }
+  int i;
+  /* Zero the histogram or inverse color map */
+  for (i = 0; i < HIST_C0_ELEMS; i++)
+    {
+      memset (histogram[i],
+             0, HIST_C1_ELEMS * HIST_C2_ELEMS * sizeof (histcell));
+    }
 }
 #endif
 
+static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP);
+
+gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int dither, int colorsWanted)
+{
+       gdImagePtr nim;
+       gdImageTrueColorToPaletteBody(im, dither, colorsWanted, &nim);
+       return nim;
+}
+
+void gdImageTrueColorToPalette (gdImagePtr im, int dither, int colorsWanted)
+{
+       gdImageTrueColorToPaletteBody(im, dither, colorsWanted, 0);
+}
+
 /*
  * Module initialization routine for 2-pass color quantization.
  */
@@ -1666,210 +1775,296 @@ static void zeroHistogram (hist3d histogram)
 GLOBAL (void)
 jinit_2pass_quantizer (j_decompress_ptr cinfo)
 #else
-void
-gdImageTrueColorToPalette (gdImagePtr im, int dither, int colorsWanted)
+static void gdImageTrueColorToPaletteBody (gdImagePtr oim, int dither, int colorsWanted, gdImagePtr *cimP)
 #endif
 {
-       my_cquantize_ptr cquantize = NULL;
-       int i;
+  my_cquantize_ptr cquantize = NULL;
+  int i;
 
 #ifndef ORIGINAL_LIB_JPEG
-       /* Allocate the JPEG palette-storage */
-       size_t arraysize;
-       int maxColors = gdMaxColors;
-       if (!im->trueColor) {
-               /* Nothing to do! */
-               return;
-       }
-
-       /* If we have a transparent color (the alphaless mode of transparency), we
-        * must reserve a palette entry for it at the end of the palette. */
-       if (im->transparent >= 0){
-               maxColors--;
-       }
-       if (colorsWanted > maxColors) {
-               colorsWanted = maxColors;
-       }
-       im->pixels = gdCalloc(sizeof (unsigned char *), im->sy);
-       for (i = 0; (i < im->sy); i++) {
-               im->pixels[i] = gdCalloc(sizeof (unsigned char *), im->sx);
-       }
+  /* Allocate the JPEG palette-storage */
+  size_t arraysize;
+  int maxColors = gdMaxColors;
+  gdImagePtr nim;
+  if (cimP) {
+    nim = gdImageCreate(oim->sx, oim->sy);
+    *cimP = nim;
+    if (!nim) {
+      return;
+    }
+  } else {
+    nim = oim;
+  }     
+  if (!oim->trueColor)
+    {
+      /* (Almost) nothing to do! */
+      if (cimP) {
+        gdImageCopy(nim, oim, 0, 0, 0, 0, oim->sx, oim->sy);
+        *cimP = nim;
+      }
+      return;
+    }
+
+  /* If we have a transparent color (the alphaless mode of transparency), we
+   * must reserve a palette entry for it at the end of the palette. */
+  if (oim->transparent >= 0)
+    {
+      maxColors--;
+    }
+  if (colorsWanted > maxColors)
+    {
+      colorsWanted = maxColors;
+    }
+  if (!cimP) {
+    nim->pixels = gdCalloc (sizeof (unsigned char *), oim->sy);
+    if (!nim->pixels)
+      {
+        /* No can do */
+        goto outOfMemory;
+      }
+    for (i = 0; (i < nim->sy); i++)
+      {
+        nim->pixels[i] = gdCalloc (sizeof (unsigned char *), oim->sx);
+        if (!nim->pixels[i])
+       {
+         goto outOfMemory;
+       }
+      }
+  }
 #endif
 
 #ifdef ORIGINAL_LIB_JPEG
-       cquantize = (my_cquantize_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF (my_cquantizer));
-       cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
-       cquantize->pub.start_pass = start_pass_2_quant;
-       cquantize->pub.new_color_map = new_color_map_2_quant;
-       /* Make sure jdmaster didn't give me a case I can't handle */
-       if (cinfo->out_color_components != 3) {
-               ERREXIT (cinfo, JERR_NOTIMPL);
-       }
+  cquantize = (my_cquantize_ptr)
+    (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+                               SIZEOF (my_cquantizer));
+  cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+  cquantize->pub.start_pass = start_pass_2_quant;
+  cquantize->pub.new_color_map = new_color_map_2_quant;
+  /* Make sure jdmaster didn't give me a case I can't handle */
+  if (cinfo->out_color_components != 3)
+    ERREXIT (cinfo, JERR_NOTIMPL);
 #else
-       cquantize = (my_cquantize_ptr) gdCalloc(sizeof (my_cquantizer), 1);
+  cquantize = (my_cquantize_ptr) gdCalloc (sizeof (my_cquantizer), 1);
+  if (!cquantize)
+    {
+      /* No can do */
+      goto outOfMemory;
+    }
 #endif
-       cquantize->fserrors = NULL;     /* flag optional arrays not allocated */
-       cquantize->error_limiter = NULL;
+  cquantize->fserrors = NULL;  /* flag optional arrays not allocated */
+  cquantize->error_limiter = NULL;
+
 
-       /* Allocate the histogram/inverse colormap storage */
+  /* Allocate the histogram/inverse colormap storage */
 #ifdef ORIGINAL_LIB_JPEG
-       cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF (hist2d));
-       for (i = 0; i < HIST_C0_ELEMS; i++) {
-               cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell));
-       }
-       cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
+  cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
+    ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF (hist2d));
+  for (i = 0; i < HIST_C0_ELEMS; i++)
+    {
+      cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
+       ((j_common_ptr) cinfo, JPOOL_IMAGE,
+        HIST_C1_ELEMS * HIST_C2_ELEMS * SIZEOF (histcell));
+    }
+  cquantize->needs_zeroed = TRUE;      /* histogram is garbage now */
 #else
-       cquantize->histogram = (hist3d) safe_emalloc(HIST_C0_ELEMS, sizeof(hist2d), 0);
-       for (i = 0; i < HIST_C0_ELEMS; i++) {
-               cquantize->histogram[i] = (hist2d) safe_emalloc(HIST_C1_ELEMS, HIST_C2_ELEMS * sizeof(histcell), 0);
+  cquantize->histogram = (hist3d) safe_emalloc (HIST_C0_ELEMS, sizeof (hist2d), 0);
+  for (i = 0; i < HIST_C0_ELEMS; i++)
+    {
+      cquantize->histogram[i] =
+       (hist2d) safe_emalloc (HIST_C1_ELEMS * HIST_C2_ELEMS, sizeof (histcell), 0);
+      if (!cquantize->histogram[i])
+       {
+         goto outOfMemory;
        }
+    }
 #endif
 
 #ifdef ORIGINAL_LIB_JPEG
-       /* Allocate storage for the completed colormap, if required.
-        * We do this now since it is FAR storage and may affect
-        * the memory manager's space calculations.
-        */
-       if (cinfo->enable_2pass_quant) {
-               /* Make sure color count is acceptable */
-               int desired = cinfo->desired_number_of_colors;
-               /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
-               if (desired < 8) {
-                       ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8);
-               }
-               /* Make sure colormap indexes can be represented by JSAMPLEs */
-               if (desired > MAXNUMCOLORS) {
-                       ERREXIT1 (cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
-               }
-               cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
-               cquantize->desired = desired;
-       } else {
-               cquantize->sv_colormap = NULL;
-       }
-
-       /* Only F-S dithering or no dithering is supported. */
-       /* If user asks for ordered dither, give him F-S. */
-       if (cinfo->dither_mode != JDITHER_NONE) {
-               cinfo->dither_mode = JDITHER_FS;
-       }
-
-       /* Allocate Floyd-Steinberg workspace if necessary.
-        * This isn't really needed until pass 2, but again it is FAR storage.
-        * Although we will cope with a later change in dither_mode,
-        * we do not promise to honor max_memory_to_use if dither_mode changes.
-        */
-       if (cinfo->dither_mode == JDITHER_FS) {
-               cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF (FSERROR))));
-               /* Might as well create the error-limiting table too. */
-               init_error_limit(cinfo);
-       }
+  /* Allocate storage for the completed colormap, if required.
+   * We do this now since it is FAR storage and may affect
+   * the memory manager's space calculations.
+   */
+  if (cinfo->enable_2pass_quant)
+    {
+      /* Make sure color count is acceptable */
+      int desired = cinfo->desired_number_of_colors;
+      /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
+      if (desired < 8)
+       ERREXIT1 (cinfo, JERR_QUANT_FEW_COLORS, 8);
+      /* Make sure colormap indexes can be represented by JSAMPLEs */
+      if (desired > MAXNUMCOLORS)
+       ERREXIT1 (cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS);
+      cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
+       ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) desired,
+        (JDIMENSION) 3);
+      cquantize->desired = desired;
+    }
+  else
+    cquantize->sv_colormap = NULL;
+
+  /* Only F-S dithering or no dithering is supported. */
+  /* If user asks for ordered dither, give him F-S. */
+  if (cinfo->dither_mode != JDITHER_NONE)
+    cinfo->dither_mode = JDITHER_FS;
+
+  /* Allocate Floyd-Steinberg workspace if necessary.
+   * This isn't really needed until pass 2, but again it is FAR storage.
+   * Although we will cope with a later change in dither_mode,
+   * we do not promise to honor max_memory_to_use if dither_mode changes.
+   */
+  if (cinfo->dither_mode == JDITHER_FS)
+    {
+      cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+       ((j_common_ptr) cinfo, JPOOL_IMAGE,
+        (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF (FSERROR))));
+      /* Might as well create the error-limiting table too. */
+      init_error_limit (cinfo);
+    }
 #else
 
-       cquantize->fserrors = (FSERRPTR) gdMalloc(3 * sizeof (FSERROR));
-       init_error_limit (im, cquantize);
-       arraysize = (size_t) ((im->sx + 2) * (3 * sizeof (FSERROR)));
-       gdFree(cquantize->fserrors);
-       /* Allocate Floyd-Steinberg workspace. */
-       cquantize->fserrors = gdCalloc(arraysize, 1);
-       cquantize->on_odd_row = FALSE;
-
-       /* Do the work! */
-       zeroHistogram(cquantize->histogram);
-       prescan_quantize(im, cquantize);
-       /* TBB 2.0.5: pass colorsWanted, not 256! */
-       select_colors(im, cquantize, colorsWanted);
-       zeroHistogram(cquantize->histogram);
-       if (dither) {
-               pass2_fs_dither(im, cquantize);
-       } else {
-               pass2_no_dither(im, cquantize);
+  cquantize->fserrors = (FSERRPTR) safe_emalloc (3, sizeof (FSERROR), 0);
+  init_error_limit (oim, nim, cquantize);
+  arraysize = (size_t) ((nim->sx + 2) * (3 * sizeof (FSERROR)));
+  /* Allocate Floyd-Steinberg workspace. */
+  cquantize->fserrors = gdCalloc (arraysize, 1);
+  if (!cquantize->fserrors)
+    {
+      goto outOfMemory;
+    }
+  cquantize->on_odd_row = FALSE;
+
+  /* Do the work! */
+  zeroHistogram (cquantize->histogram);
+  prescan_quantize (oim, nim, cquantize);
+  /* TBB 2.0.5: pass colorsWanted, not 256! */
+  select_colors (oim, nim, cquantize, colorsWanted);
+  zeroHistogram (cquantize->histogram);
+  if (dither)
+    {
+      pass2_fs_dither (oim, nim, cquantize);
+    }
+  else
+    {
+      pass2_no_dither (oim, nim, cquantize);
+    }
+#if 0                          /* 2.0.12; we no longer attempt full alpha in palettes */
+  if (cquantize->transparentIsPresent)
+    {
+      int mt = -1;
+      int mtIndex = -1;
+      for (i = 0; (i < im->colorsTotal); i++)
+       {
+         if (im->alpha[i] > mt)
+           {
+             mtIndex = i;
+             mt = im->alpha[i];
+           }
        }
-#if 0  /* 2.0.12; we no longer attempt full alpha in palettes */
-       if (cquantize->transparentIsPresent) {
-               int mt = -1;
-               int mtIndex = -1;
-               for (i = 0; (i < im->colorsTotal); i++) {
-                       if (im->alpha[i] > mt) {
-                               mtIndex = i;
-                               mt = im->alpha[i];
-                       }
-               }
-               for (i = 0; (i < im->colorsTotal); i++) {
-                       if (im->alpha[i] == mt) {
-                               im->alpha[i] = gdAlphaTransparent;
-                       }
-               }
+      for (i = 0; (i < im->colorsTotal); i++)
+       {
+         if (im->alpha[i] == mt)
+           {
+             im->alpha[i] = gdAlphaTransparent;
+           }
        }
-       if (cquantize->opaqueIsPresent) {
-               int mo = 128;
-               int moIndex = -1;
-               for (i = 0; (i < im->colorsTotal); i++) {
-                       if (im->alpha[i] < mo) {
-                               moIndex = i;
-                               mo = im->alpha[i];
-                       }
-               }
-               for (i = 0; (i < im->colorsTotal); i++) {
-                       if (im->alpha[i] == mo) {
-                               im->alpha[i] = gdAlphaOpaque;
-                       }
-               }
+    }
+  if (cquantize->opaqueIsPresent)
+    {
+      int mo = 128;
+      int moIndex = -1;
+      for (i = 0; (i < im->colorsTotal); i++)
+       {
+         if (im->alpha[i] < mo)
+           {
+             moIndex = i;
+             mo = im->alpha[i];
+           }
+       }
+      for (i = 0; (i < im->colorsTotal); i++)
+       {
+         if (im->alpha[i] == mo)
+           {
+             im->alpha[i] = gdAlphaOpaque;
+           }
        }
+    }
 #endif
 
-       /* If we had a 'transparent' color, increment the color count so it's
-        * officially in the palette and convert the transparent variable to point to
-        * an index rather than a color (Its data already exists and transparent
-        * pixels have already been mapped to it by this point, it is done late as to
-        * avoid color matching / dithering with it). */
-       if (im->transparent >= 0) {
-               im->transparent = im->colorsTotal;
-               im->colorsTotal++;
+  /* If we had a 'transparent' color, increment the color count so it's
+   * officially in the palette and convert the transparent variable to point to
+   * an index rather than a color (Its data already exists and transparent
+   * pixels have already been mapped to it by this point, it is done late as to
+   * avoid color matching / dithering with it). */
+  if (oim->transparent >= 0)
+    {
+      nim->transparent = nim->colorsTotal;
+      nim->colorsTotal++;
+    }
+
+  /* Success! Get rid of the truecolor image data. */
+  if (!cimP) { 
+    oim->trueColor = 0;
+    /* Junk the truecolor pixels */
+    for (i = 0; i < oim->sy; i++)
+      {
+        gdFree (oim->tpixels[i]);
+      }
+    gdFree (oim->tpixels);
+    oim->tpixels = 0;
+  }
+  goto success;
+  /* Tediously free stuff. */
+outOfMemory:
+  if (oim->trueColor)
+    {
+      if (!cimP) {
+        /* On failure only */
+        for (i = 0; i < nim->sy; i++)
+       {
+         if (nim->pixels[i])
+           {
+             gdFree (nim->pixels[i]);
+           }
+       }
+        if (nim->pixels)
+       {
+         gdFree (nim->pixels);
+       }
+        nim->pixels = 0;
+      } else {
+        gdImageDestroy(nim);
+        *cimP = 0;
+      }
+    }
+success:
+  for (i = 0; i < HIST_C0_ELEMS; i++)
+    {
+      if (cquantize->histogram[i])
+       {
+         gdFree (cquantize->histogram[i]);
        }
+    }
+  if (cquantize->histogram)
+    {
+      gdFree (cquantize->histogram);
+    }
+  if (cquantize->fserrors)
+    {
+      gdFree (cquantize->fserrors);
+    }
+  if (cquantize->error_limiter_storage)
+    {
+      gdFree (cquantize->error_limiter_storage);
+    }
+  if (cquantize)
+    {
+      gdFree (cquantize);
+    }
 
-       /* Success! Get rid of the truecolor image data. */
-       im->trueColor = 0;
-       /* Junk the truecolor pixels */
-       for (i = 0; i < im->sy; i++) {
-               gdFree(im->tpixels[i]);
-       }
-       gdFree(im->tpixels);
-       im->tpixels = 0;
-       /* Tediously free stuff. */
-
-       if (im->trueColor) {
-               /* On failure only */
-               for (i = 0; i < im->sy; i++) {
-                       if (im->pixels[i]) {
-                               gdFree (im->pixels[i]);
-                       }
-               }
-               if (im->pixels) {
-                       gdFree (im->pixels);
-               }
-               im->pixels = 0;
-       }
-
-       for (i = 0; i < HIST_C0_ELEMS; i++) {
-               if (cquantize->histogram[i]) {
-                       gdFree(cquantize->histogram[i]);
-               }
-       }
-       if (cquantize->histogram) {
-               gdFree(cquantize->histogram);
-       }
-       if (cquantize->fserrors) {
-               gdFree(cquantize->fserrors);
-       }
-       if (cquantize->error_limiter_storage) {
-               gdFree(cquantize->error_limiter_storage);
-       }
-       if (cquantize) {
-               gdFree(cquantize);
-       }
 #endif
 }
 
+
 /* bring the palette colors in im2 to be closer to im1
  *
  */